diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,72 @@
+======================================================================
+Haskell LLVM Bindings Release License
+======================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2014      Henning Thielemann
+Copyright (c) 2007-2009 Bryan O'Sullivan
+All rights reserved.
+
+Developed by:
+
+    Henning Thielemann <llvm@henning-thielemann.de>
+
+    Bryan O'Sullivan <bos@serpentine.com>
+    http://www.serpentine.com/blog/
+
+    Lennart Augustsson <lennart@augustsson.net>
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal with the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimers.
+
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimers in the documentation and/or other materials provided
+      with the distribution.
+
+    * Neither the names of Bryan O'Sullivan, University of Illinois at
+      Urbana-Champaign, nor the names of its contributors may be used
+      to endorse or promote products derived from this Software
+      without specific prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR
+ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
+CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
+
+======================================================================
+Copyrights and Licenses for Third Party Software Distributed with
+Haskell LLVM Bindings:
+======================================================================
+
+The Haskell LLVM Bindings software may contain code written by third
+parties.  Any such software will have its own individual license file
+in the directory in which it appears.  This file will describe the
+copyrights, license, and restrictions which apply to that code.
+
+The disclaimer of warranty in the University of Illinois Open Source
+License applies to all code in the Haskell LLVM Bindings Distribution,
+and nothing in any of the other licenses gives permission to use the
+name of Bryan O'Sullivan or the University of Illinois to endorse or
+promote products derived from this Software.
+
+The following pieces of software have additional or alternate
+copyrights, licenses, and/or restrictions:
+
+Program             Directory
+-------             ---------
+configure           .
+
+
diff --git a/Setup.lhs b/Setup.lhs
new file mode 100644
--- /dev/null
+++ b/Setup.lhs
@@ -0,0 +1,3 @@
+#!/usr/bin/env runhaskell
+> import Distribution.Simple
+> main = defaultMain
diff --git a/cbits/extra.cpp b/cbits/extra.cpp
new file mode 100644
--- /dev/null
+++ b/cbits/extra.cpp
@@ -0,0 +1,568 @@
+/*
+ * Copyright (c) 2008-10, Mahadevan R All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of this software, nor the names of its 
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * These are some "extra" functions not available in the standard LLVM-C
+ * bindings, but are required / good-to-have inorder to implement the
+ * Python bindings.
+ */
+
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS
+#endif
+
+// standard includes
+#include <cassert>
+#include <cstdlib>
+#include <cstring>
+#include <sstream>
+
+// LLVM includes
+#include "llvm/LLVMContext.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/GlobalVariable.h"
+#if HS_LLVM_VERSION < 300
+#include "llvm/TypeSymbolTable.h"
+#endif
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Assembly/Parser.h"
+#ifdef HAVE_LLVM_SUPPORT_DYNAMICLIBRARY_H
+# include "llvm/Support/DynamicLibrary.h"
+#else
+# include "llvm/System/DynamicLibrary.h"
+#endif
+#include "llvm/PassManager.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/DomPrinter.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
+#include "llvm/Transforms/Instrumentation.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Linker.h"
+#include "llvm/Support/SourceMgr.h"
+
+// LLVM-C includes
+#include "llvm-c/Core.h"
+#include "llvm-c/ExecutionEngine.h"
+#include "llvm-c/Target.h"
+
+// our includes
+#include "extra.h"
+
+//using namespace llvm;
+
+unsigned LLVMInitNativeTarget()
+{
+    return LLVMInitializeNativeTarget();
+}
+
+char *LLVMDumpModuleToString(LLVMModuleRef module)
+{
+    std::string s;
+    llvm::raw_string_ostream buf(s);
+    llvm::Module *p = llvm::unwrap(module);
+    assert(p);
+    p->print(buf, NULL);
+    return strdup(buf.str().c_str());
+}
+
+char *LLVMDumpTypeToString(LLVMTypeRef type)
+{
+    std::string s;
+    llvm::raw_string_ostream buf(s);
+    llvm::Type *p = llvm::unwrap(type);
+    assert(p);
+    p->print(buf);
+    return strdup(buf.str().c_str());
+}
+
+char *LLVMDumpValueToString(LLVMValueRef value)
+{
+    std::string s;
+    llvm::raw_string_ostream buf(s);
+    llvm::Value *p = llvm::unwrap(value);
+    assert(p);
+    p->print(buf);
+    return strdup(buf.str().c_str());
+}
+
+unsigned LLVMModuleGetPointerSize(LLVMModuleRef module)
+{
+    llvm::Module *modulep = llvm::unwrap(module);
+    assert(modulep);
+
+    llvm::Module::PointerSize p = modulep->getPointerSize();
+    if (p == llvm::Module::Pointer32)
+        return 32;
+    else if (p == llvm::Module::Pointer64)
+        return 64;
+    return 0;
+}
+
+LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef module,
+    const char *name, LLVMTypeRef function_type)
+{
+    assert(name);
+
+    llvm::Module *modulep = llvm::unwrap(module);
+    assert(modulep);
+
+    llvm::FunctionType *ftp = llvm::unwrap<llvm::FunctionType>(function_type);
+    assert(ftp);
+
+    llvm::Constant *f = modulep->getOrInsertFunction(name, ftp);
+    return wrap(f);
+}
+
+int LLVMHasInitializer(LLVMValueRef global_var)
+{
+    llvm::GlobalVariable *gvp = llvm::unwrap<llvm::GlobalVariable>(global_var);
+    assert(gvp);
+
+    return gvp->hasInitializer();
+}
+
+#define inst_checkfn(ourfn, llvmfn)                 \
+unsigned ourfn (LLVMValueRef v) {                   \
+    llvm::Instruction *ip = llvm::unwrap<llvm::Instruction>(v); \
+    assert(ip);                                     \
+    return ip-> llvmfn () ? 1 : 0;                  \
+}
+
+inst_checkfn(LLVMInstIsTerminator,      isTerminator)
+inst_checkfn(LLVMInstIsBinaryOp,        isBinaryOp)
+inst_checkfn(LLVMInstIsShift,           isShift)
+inst_checkfn(LLVMInstIsCast,            isCast)
+inst_checkfn(LLVMInstIsLogicalShift,    isLogicalShift)
+inst_checkfn(LLVMInstIsArithmeticShift, isArithmeticShift)
+inst_checkfn(LLVMInstIsAssociative,     isAssociative)
+inst_checkfn(LLVMInstIsCommutative,     isCommutative)
+
+unsigned LLVMInstIsVolatile(LLVMValueRef v)
+{
+    using namespace llvm;
+    Instruction *ip = unwrap<Instruction>(v);
+    assert(ip);
+    return ((isa<LoadInst>(*ip)  && cast<LoadInst>(*ip).isVolatile()) ||
+            (isa<StoreInst>(*ip) && cast<StoreInst>(*ip).isVolatile()) );
+}
+
+const char *LLVMInstGetOpcodeName(LLVMValueRef inst)
+{
+    llvm::Instruction *instp = llvm::unwrap<llvm::Instruction>(inst);
+    assert(instp);
+    return instp->getOpcodeName();
+}
+
+unsigned LLVMInstGetOpcode(LLVMValueRef inst)
+{
+    llvm::Instruction *instp = llvm::unwrap<llvm::Instruction>(inst);
+    assert(instp);
+    return instp->getOpcode();
+}
+
+unsigned LLVMCmpInstGetPredicate(LLVMValueRef cmpinst)
+{
+    llvm::CmpInst *instp = llvm::unwrap<llvm::CmpInst>(cmpinst);
+    assert(instp);
+    return instp->getPredicate();
+}
+
+/* llvm::unwrap a set of `n' wrapped objects starting at `values',
+ * into a vector of pointers to llvm::unwrapped objects `out'. */
+template <typename W, typename UW>
+static inline void unwrap_vec(W *values, unsigned n, std::vector<UW *>& out)
+{
+    out.clear();
+
+    while (n--) {
+        UW *p = llvm::unwrap(*values);
+        assert(p);
+        out.push_back(p);
+        ++values;
+    }
+}
+
+/* Same as llvm::unwrap_vec, but use a vector of const pointers. */
+template <typename W, typename UW>
+static inline void unwrap_cvec(W *values, unsigned n, std::vector<const UW *>& out)
+{
+    out.clear();
+
+    while (n--) {
+        UW *p = llvm::unwrap(*values);
+        assert(p);
+        out.push_back(p);
+        ++values;
+    }
+}
+
+LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef builder, 
+    LLVMValueRef *values, unsigned n_values)
+{
+    assert(values);
+
+    std::vector<llvm::Value *> values_vec;
+    unwrap_vec<LLVMValueRef, llvm::Value>(values, n_values, values_vec);
+
+    llvm::IRBuilder<> *builderp = llvm::unwrap(builder);
+    assert(builderp);
+
+    return llvm::wrap(builderp->CreateAggregateRet(&values_vec[0], values_vec.size()));
+}
+
+LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, 
+    LLVMValueRef value, unsigned index, const char *name)
+{
+    assert(name);
+
+    llvm::IRBuilder<> *builderp = llvm::unwrap(builder);
+    assert(builderp);
+
+    return llvm::wrap(builderp->CreateExtractValue(llvm::unwrap(value), index, name));
+}
+
+unsigned LLVMValueGetID(LLVMValueRef value)
+{
+    llvm::Value *valuep = llvm::unwrap(value);
+    assert(valuep);
+
+    return valuep->getValueID();
+}
+
+unsigned LLVMValueGetNumUses(LLVMValueRef value)
+{
+    llvm::Value *valuep = llvm::unwrap(value);
+    assert(valuep);
+
+    return valuep->getNumUses();
+}
+
+unsigned LLVMValueGetUses(LLVMValueRef value, LLVMValueRef **refs)
+{
+    llvm::Value *valuep = llvm::unwrap(value);
+    assert(valuep);
+
+    unsigned n = valuep->getNumUses();
+    if (n == 0)
+        return 0;
+
+    assert(refs);
+    LLVMValueRef *out = (LLVMValueRef *)malloc(sizeof(LLVMValueRef) * n);
+    if (!out)
+        return 0;
+    *refs = out;
+
+    memset(out, 0, sizeof(LLVMValueRef) * n);
+    llvm::Value::use_iterator it = valuep->use_begin();
+    while (it != valuep->use_end()) {
+        *out++ = llvm::wrap(*it);
+        ++it;
+    }
+
+    return n;
+}
+
+unsigned LLVMValueIsUsedInBasicBlock(LLVMValueRef value, LLVMBasicBlockRef bb)
+{
+    llvm::Value *valuep = llvm::unwrap(value);
+    assert(valuep);
+    llvm::BasicBlock *bbp = llvm::unwrap(bb);
+    assert(bbp);
+    return valuep->isUsedInBasicBlock(bbp);
+}
+
+void LLVMDisposeValueRefArray(LLVMValueRef *refs)
+{
+    assert(refs);
+    free(refs);
+}
+
+unsigned LLVMUserGetNumOperands(LLVMValueRef user)
+{
+    llvm::User *userp = llvm::unwrap<llvm::User>(user);
+    assert(userp);
+    return userp->getNumOperands();
+}
+
+LLVMValueRef LLVMUserGetOperand(LLVMValueRef user, unsigned idx)
+{
+    llvm::User *userp = llvm::unwrap<llvm::User>(user);
+    assert(userp);
+    llvm::Value *operand = userp->getOperand(idx);
+    return llvm::wrap(operand);
+}
+
+unsigned LLVMGetDoesNotThrow(LLVMValueRef fn)
+{
+    llvm::Function *fnp = llvm::unwrap<llvm::Function>(fn);
+    assert(fnp);
+
+    return fnp->doesNotThrow();
+}
+
+void LLVMSetDoesNotThrow(LLVMValueRef fn, int DoesNotThrow)
+{
+    llvm::Function *fnp = llvm::unwrap<llvm::Function>(fn);
+    assert(fnp);
+
+    return fnp->setDoesNotThrow((bool)DoesNotThrow);
+}
+
+LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef module, int id,
+    LLVMTypeRef *types, unsigned n_types)
+{
+    assert(types);
+
+#if HS_LLVM_VERSION >= 300
+    std::vector<llvm::Type*> types_vec;
+    unwrap_vec<LLVMTypeRef, llvm::Type>(types, n_types, types_vec);
+#else
+    std::vector<const llvm::Type*> types_vec;
+    unwrap_cvec<LLVMTypeRef, llvm::Type>(types, n_types, types_vec);
+#endif
+
+    llvm::Module *modulep = llvm::unwrap(module);
+    assert(modulep);
+
+#if HS_LLVM_VERSION >= 300
+    llvm::Function *intfunc = llvm::Intrinsic::getDeclaration(modulep, 
+        llvm::Intrinsic::ID(id), types_vec);
+#else
+    llvm::Function *intfunc = llvm::Intrinsic::getDeclaration(modulep, 
+        llvm::Intrinsic::ID(id), &types_vec[0], types_vec.size());
+#endif
+    return wrap(intfunc);
+}
+
+LLVMModuleRef LLVMGetModuleFromAssembly(const char *asmtext, unsigned txtlen,
+    char **out)
+{
+    assert(asmtext);
+    assert(out);
+
+    llvm::Module *modulep;
+    llvm::SMDiagnostic error;
+    if (!(modulep = llvm::ParseAssemblyString(asmtext, NULL, error,
+                                              llvm::getGlobalContext()))) {
+        std::string s;
+        llvm::raw_string_ostream buf(s);
+        error.Print("llvm-py", buf);
+        *out = strdup(buf.str().c_str());
+        return NULL;
+    }
+
+    return wrap(modulep);
+}
+
+LLVMModuleRef LLVMGetModuleFromBitcode(const char *bitcode, unsigned bclen,
+    char **out)
+{
+    assert(bitcode);
+    assert(out);
+
+    llvm::StringRef as_str(bitcode, bclen);
+
+    llvm::MemoryBuffer *mbp;
+    if (!(mbp = llvm::MemoryBuffer::getMemBufferCopy(as_str)))
+        return NULL;
+
+    std::string msg;
+    llvm::Module *modulep;
+    if (!(modulep = llvm::ParseBitcodeFile(mbp, llvm::getGlobalContext(),
+                                           &msg)))
+        *out = strdup(msg.c_str());
+
+    delete mbp;
+    return wrap(modulep);
+}
+
+unsigned LLVMLinkModules(LLVMModuleRef dest, LLVMModuleRef src, unsigned mode,
+			 char **out)
+{
+    llvm::Module *sourcep = llvm::unwrap(src);
+    assert(sourcep);
+    llvm::Module *destinationp = llvm::unwrap(dest);
+    assert(destinationp);
+
+    std::string msg;
+    bool err;
+
+#if HS_LLVM_VERSION >= 300    
+    err = llvm::Linker::LinkModules(destinationp, sourcep, mode, &msg);
+#else
+    err = llvm::Linker::LinkModules(destinationp, sourcep, &msg);
+#endif
+
+    if (err) {
+        *out = strdup(msg.c_str());
+        return 0;
+    }
+
+    return 1;
+}
+
+unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef module, unsigned *lenp)
+{
+    assert(lenp);
+
+    llvm::Module *modulep = llvm::unwrap(module);
+    assert(modulep);
+
+    /* get bc into a string */
+    std::string s;
+    llvm::raw_string_ostream buf(s);
+    llvm::WriteBitcodeToFile(modulep, buf);
+    const std::string& bc = buf.str();
+
+    /* and then into a malloc()-ed block */
+    size_t bclen = bc.size();
+    unsigned char *bytes = (unsigned char *)malloc(bclen);
+    if (!bytes)
+        return NULL;
+    memcpy(bytes, bc.data(), bclen);
+
+    /* return */
+    *lenp = bclen;
+    return bytes;
+}
+
+/* Return 0 on failure (with errmsg filled in), 1 on success. */
+unsigned LLVMLoadLibraryPermanently(const char* filename, char **errmsg)
+{
+    assert(filename);
+    assert(errmsg);
+
+    /* Note: the LLVM API returns true on failure. Don't ask why. */
+    std::string msg;
+    if (llvm::sys::DynamicLibrary::LoadLibraryPermanently(filename, &msg)) {
+        *errmsg = strdup(msg.c_str());
+        return 0;
+    }
+
+    return 1;
+}
+
+void *LLVMGetPointerToFunction(LLVMExecutionEngineRef ee, LLVMValueRef fn)
+{
+    llvm::ExecutionEngine *eep = llvm::unwrap(ee);
+    assert(eep);
+
+    llvm::Function *fnp = llvm::unwrap<llvm::Function>(fn);
+    assert(fnp);
+
+    return eep->getPointerToFunction(fnp);
+}
+
+int LLVMInlineFunction(LLVMValueRef call)
+{
+    llvm::Value *callp = llvm::unwrap(call);
+    assert(callp);
+
+    llvm::CallSite cs = llvm::CallSite(callp);
+
+    llvm::InlineFunctionInfo unused;
+    return llvm::InlineFunction(cs, unused);
+}
+
+
+/* Passes. A few passes (listed below) are used directly from LLVM-C,
+ * rest are defined here.
+ */
+
+#define define_pass(P)                                   \
+void LLVMAdd ## P ## Pass (LLVMPassManagerRef passmgr) { \
+    using namespace llvm;                                \
+    llvm::PassManagerBase *pmp = llvm::unwrap(passmgr);  \
+    assert(pmp);                                         \
+    pmp->add( create ## P ## Pass ());                   \
+}
+
+define_pass( AAEval )
+define_pass( AliasAnalysisCounter )
+define_pass( AlwaysInliner )
+define_pass( BasicAliasAnalysis )
+define_pass( BlockPlacement )
+define_pass( BreakCriticalEdges )
+define_pass( CodeGenPrepare )
+define_pass( DbgInfoPrinter )
+define_pass( DeadCodeElimination )
+define_pass( DeadInstElimination )
+define_pass( DemoteRegisterToMemory )
+define_pass( DomOnlyPrinter )
+define_pass( DomOnlyViewer )
+define_pass( DomPrinter )
+define_pass( DomViewer )
+define_pass( EdgeProfiler )
+define_pass( GlobalsModRef )
+define_pass( InstCount )
+define_pass( InstructionNamer )
+define_pass( LazyValueInfo )
+define_pass( LCSSA )
+define_pass( LoopDependenceAnalysis )
+define_pass( LoopExtractor )
+define_pass( LoopSimplify )
+define_pass( LoopStrengthReduce )
+define_pass( LowerInvoke )
+define_pass( LowerSwitch )
+define_pass( MergeFunctions )
+define_pass( NoAA )
+define_pass( NoProfileInfo )
+define_pass( OptimalEdgeProfiler )
+define_pass( PartialInlining )
+define_pass( PostDomOnlyPrinter )
+define_pass( PostDomOnlyViewer )
+define_pass( PostDomPrinter )
+define_pass( PostDomViewer )
+define_pass( ProfileEstimator )
+define_pass( ProfileLoader )
+define_pass( ProfileVerifier )
+define_pass( ScalarEvolutionAliasAnalysis )
+define_pass( SingleLoopExtractor )
+define_pass( StripNonDebugSymbols )
+define_pass( UnifyFunctionExitNodes )
+
+/* we support only internalize(true) */
+llvm::ModulePass *createInternalize2Pass() { return llvm::createInternalizePass(true); }
+define_pass( Internalize2 )
+
diff --git a/cbits/support.cpp b/cbits/support.cpp
new file mode 100644
--- /dev/null
+++ b/cbits/support.cpp
@@ -0,0 +1,92 @@
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+#ifndef __STDC_CONSTANT_MACROS
+#define __STDC_CONSTANT_MACROS
+#endif
+
+#include "llvm-c/Core.h"
+#include "llvm/PassManager.h"
+#if HS_LLVM_VERSION >= 300
+# include "llvm/DefaultPasses.h"
+# include "llvm/Transforms/IPO/PassManagerBuilder.h"
+# include "llvm/Transforms/IPO.h"
+#else
+# include "llvm/Support/StandardPasses.h"
+#endif
+
+#include "support.h"
+
+using namespace llvm;
+
+void LLVMCreateStandardFunctionPasses(LLVMPassManagerRef PM,
+					unsigned OptimizationLevel)
+{
+#if HS_LLVM_VERSION >= 300
+  llvm::PassManagerBuilder Builder;
+  Builder.OptLevel = OptimizationLevel;
+
+  llvm::PassManagerBase *pass_man = unwrap(PM);
+  llvm::FunctionPassManager *func_man =
+    dynamic_cast <FunctionPassManager*>(pass_man);
+
+  if (func_man) {
+    Builder.populateFunctionPassManager (*func_man);
+  } else {
+    // printf ("Cannot create function passes for module pass manager\n");
+  }
+#else
+  createStandardFunctionPasses(unwrap(PM), OptimizationLevel);
+#endif
+}
+
+void LLVMCreateStandardModulePasses(LLVMPassManagerRef PM,
+				    unsigned OptLevel,
+				    int OptimizeSize,
+				    int UnitAtATime,
+				    int UnrollLoops,
+				    int SimplifyLibCalls,
+				    int HaveExceptions,
+				    int DisableInline)
+{
+#if HS_LLVM_VERSION >= 300
+  llvm::PassManagerBuilder Builder;
+  Builder.OptLevel = OptLevel;
+  Builder.SizeLevel = OptimizeSize;
+  Builder.DisableUnrollLoops = !UnrollLoops;
+  Builder.DisableSimplifyLibCalls = !SimplifyLibCalls;
+  Builder.DisableUnitAtATime = !UnitAtATime;
+    
+  Pass *InliningPass = 0;
+
+  if (DisableInline) {
+    // No inlining pass
+  } else if (OptLevel) {
+    unsigned Threshold = 225;
+    if (OptLevel > 2)
+      Threshold = 275;
+    Builder.Inliner = createFunctionInliningPass(Threshold);
+  } else {
+    Builder.Inliner = createAlwaysInlinerPass();
+  }
+
+  Builder.populateModulePassManager (*unwrap(PM));
+#else
+  Pass *InliningPass = 0;
+
+  if (DisableInline) {
+    // No inlining pass
+  } else if (OptLevel) {
+    unsigned Threshold = 225;
+    if (OptLevel > 2)
+      Threshold = 275;
+    InliningPass = createFunctionInliningPass(Threshold);
+  } else {
+    InliningPass = createAlwaysInlinerPass();
+  }
+
+  createStandardModulePasses(unwrap(PM), OptLevel, OptimizeSize,
+                             UnitAtATime, UnrollLoops, SimplifyLibCalls,
+                             HaveExceptions, InliningPass);
+#endif
+}
diff --git a/include/extra.h b/include/extra.h
new file mode 100644
--- /dev/null
+++ b/include/extra.h
@@ -0,0 +1,253 @@
+/*
+ * Copyright (c) 2008-10, Mahadevan R All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  * Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ *  * Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ *  * Neither the name of this software, nor the names of its 
+ *    contributors may be used to endorse or promote products derived from
+ *    this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * These are some "extra" functions not available in the standard LLVM-C
+ * bindings, but are required / good-to-have inorder to implement the
+ * Python bindings.
+ */
+
+#ifndef LLVM_PY_EXTRA_H
+#define LLVM_PY_EXTRA_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Notes:
+ *  - Some returned strings must be disposed of by LLVMDisposeMessage. These are
+ *    indicated in the comments. Where it is not indicated, DO NOT call dispose.
+ */
+
+
+/* Wraps the LLVMInitializeTarget macro from Target.h */
+unsigned LLVMInitNativeTarget(void);
+
+
+/* Wraps llvm::Module::print(). Dispose the returned string after use, via
+ * LLVMDisposeMessage(). */
+char *LLVMDumpModuleToString(LLVMModuleRef module);
+
+/* Wraps llvm::Type::print(). Dispose the returned string after use, via
+ * LLVMDisposeMessage(). */
+char *LLVMDumpTypeToString(LLVMTypeRef type);
+
+/* Wraps llvm::Value::print(). Dispose the returned string after use, via
+ * LLVMDisposeMessage(). */
+char *LLVMDumpValueToString(LLVMValueRef Val);
+
+/* Wraps llvm::IRBuilder::CreateRet(). */
+LLVMValueRef LLVMBuildRetMultiple(LLVMBuilderRef bulder, LLVMValueRef *values,
+    unsigned n_values);
+
+/* Wraps llvm::IRBuilder::CreateGetResult(). */
+LLVMValueRef LLVMBuildGetResult(LLVMBuilderRef builder, LLVMValueRef value,
+    unsigned index, const char *name);
+
+/* Wraps llvm::Value::getValueID(). */
+unsigned LLVMValueGetID(LLVMValueRef value);
+
+/* Wraps llvm::Value::getNumUses(). */
+unsigned LLVMValueGetNumUses(LLVMValueRef value);
+
+/* Wraps llvm::Value::use_{begin,end}. Allocates LLVMValueRef's as
+ * required. Number of objects are returned as return value. If that is
+ * greater than zero, the pointer given out must be freed by a
+ * subsequent call to LLVMDisposeValueRefArray(). */
+unsigned LLVMValueGetUses(LLVMValueRef value, LLVMValueRef **refs);
+
+/* Wraps llvm::Value::isUsedInBasicBlock(). */
+unsigned LLVMValueIsUsedInBasicBlock(LLVMValueRef value, LLVMBasicBlockRef bb);
+/* See above. */
+void LLVMDisposeValueRefArray(LLVMValueRef *refs);
+
+/* Wraps llvm:User::getNumOperands(). */
+unsigned LLVMUserGetNumOperands(LLVMValueRef user);
+
+/* Wraps llvm:User::getOperand(). */
+LLVMValueRef LLVMUserGetOperand(LLVMValueRef user, unsigned idx);
+
+/* Wraps llvm::ConstantExpr::getVICmp(). */
+LLVMValueRef LLVMConstVICmp(LLVMIntPredicate predicate, LLVMValueRef lhs,
+    LLVMValueRef rhs);
+
+/* Wraps llvm::ConstantExpr::getVFCmp(). */
+LLVMValueRef LLVMConstVFCmp(LLVMRealPredicate predicate, LLVMValueRef lhs,
+    LLVMValueRef rhs);
+
+/* Wraps llvm::IRBuilder::CreateVICmp(). */    
+LLVMValueRef LLVMBuildVICmp(LLVMBuilderRef builder, LLVMIntPredicate predicate,
+    LLVMValueRef lhs, LLVMValueRef rhs, const char *name);
+
+/* Wraps llvm::IRBuilder::CreateVFCmp(). */    
+LLVMValueRef LLVMBuildVFCmp(LLVMBuilderRef builder, LLVMRealPredicate predicate,
+    LLVMValueRef lhs, LLVMValueRef rhs, const char *name);
+    
+/* Wraps llvm::Intrinsic::getDeclaration(). */
+LLVMValueRef LLVMGetIntrinsic(LLVMModuleRef builder, int id,
+    LLVMTypeRef *types, unsigned n_types);
+
+/* Wraps llvm::Function::doesNotThrow(). */
+unsigned LLVMGetDoesNotThrow(LLVMValueRef fn);
+
+/* Wraps llvm::Function::setDoesNotThrow(). */
+void LLVMSetDoesNotThrow(LLVMValueRef fn, int DoesNotThrow);
+
+/* Wraps llvm::Module::getPointerSize(). */
+unsigned LLVMModuleGetPointerSize(LLVMModuleRef module);
+
+/* Wraps llvm::Module::getOrInsertFunction(). */
+LLVMValueRef LLVMModuleGetOrInsertFunction(LLVMModuleRef module, 
+    const char *name, LLVMTypeRef function_type);
+
+/* Wraps llvm::GlobalVariable::hasInitializer(). */    
+int LLVMHasInitializer(LLVMValueRef global_var);
+    
+/* The following functions wrap various llvm::Instruction::isXXX() functions.
+ * All of them take an instruction and return 0 (isXXX returned false) or 1
+ * (isXXX returned false). */
+unsigned LLVMInstIsTerminator      (LLVMValueRef inst);
+unsigned LLVMInstIsBinaryOp        (LLVMValueRef inst);
+unsigned LLVMInstIsShift           (LLVMValueRef inst);
+unsigned LLVMInstIsCast            (LLVMValueRef inst);
+unsigned LLVMInstIsLogicalShift    (LLVMValueRef inst);
+unsigned LLVMInstIsArithmeticShift (LLVMValueRef inst);
+unsigned LLVMInstIsAssociative     (LLVMValueRef inst);
+unsigned LLVMInstIsCommutative     (LLVMValueRef inst);
+unsigned LLVMInstIsTrapping        (LLVMValueRef inst);
+
+/* As above, but these are wrap methods from subclasses of Instruction. */
+unsigned LLVMInstIsVolatile        (LLVMValueRef inst);
+
+/* Wraps llvm::Instruction::getOpcodeName(). */
+const char *LLVMInstGetOpcodeName(LLVMValueRef inst);
+
+/* Wraps llvm::Instruction::getOpcode(). */
+unsigned LLVMInstGetOpcode(LLVMValueRef inst);
+
+/* Wraps llvm::CmpInst::getPredicate(). */
+unsigned LLVMCmpInstGetPredicate(LLVMValueRef cmpinst);
+
+/* Wraps llvm::ParseAssemblyString(). Returns a module reference or NULL (with
+ * `out' pointing to an error message). Dispose error message after use, via
+ * LLVMDisposeMessage(). */
+LLVMModuleRef LLVMGetModuleFromAssembly(const char *asmtxt, unsigned txten,
+    char **out);
+
+/* Wraps llvm::ParseBitcodeFile(). Returns a module reference or NULL (with
+ * `out' pointing to an error message). Dispose error message after use, via
+ * LLVMDisposeMessage(). */
+LLVMModuleRef LLVMGetModuleFromBitcode(const char *bc, unsigned bclen,
+    char **out);
+
+/* Wraps llvm::Linker::LinkModules().  Returns 0 on failure (with errmsg
+ * filled in) and 1 on success.  Dispose error message after use with
+ * LLVMDisposeMessage(). */
+unsigned LLVMLinkModules(LLVMModuleRef dest, LLVMModuleRef src,
+			 unsigned mode, char **errmsg);
+
+/* Returns pointer to a heap-allocated block of `*len' bytes containing bit code
+ * for the given module. NULL on error. */
+unsigned char *LLVMGetBitcodeFromModule(LLVMModuleRef module, unsigned *len);
+
+/* Wraps llvm::sys::DynamicLibrary::LoadLibraryPermanently(). Returns 0 on
+ * failure (with errmsg filled in) and 1 on success. Dispose error message after
+ * use, via LLVMDisposeMessage(). */
+unsigned LLVMLoadLibraryPermanently(const char* filename, char **errmsg);
+
+/* Wraps llvm::ExecutionEngine::getPointerToFunction(). Returns a pointer 
+ * to the JITted function. */
+void *LLVMGetPointerToFunction(LLVMExecutionEngineRef ee, LLVMValueRef fn);
+
+/* Wraps llvm::InlineFunction(). Inlines a function. C is the call 
+ * instruction, created by LLVMBuildCall. Even if it fails, the Function 
+ * containing the call is still in a proper state (not changed). */
+int LLVMInlineFunction(LLVMValueRef call);
+
+/* Passes. Some passes are used directly from LLVM-C, rest are declared
+ * here. */
+
+#define declare_pass(P) \
+    void LLVMAdd ## P ## Pass (LLVMPassManagerRef PM);
+
+declare_pass( AAEval )
+declare_pass( AliasAnalysisCounter )
+declare_pass( AlwaysInliner )
+declare_pass( BasicAliasAnalysis )
+declare_pass( BlockPlacement )
+declare_pass( BreakCriticalEdges )
+declare_pass( CodeGenPrepare )
+declare_pass( DbgInfoPrinter )
+declare_pass( DeadCodeElimination )
+declare_pass( DeadInstElimination )
+declare_pass( DemoteRegisterToMemory )
+declare_pass( DomOnlyPrinter )
+declare_pass( DomOnlyViewer )
+declare_pass( DomPrinter )
+declare_pass( DomViewer )
+declare_pass( EdgeProfiler )
+declare_pass( GlobalsModRef )
+declare_pass( InstCount )
+declare_pass( InstructionNamer )
+declare_pass( LazyValueInfo )
+declare_pass( LCSSA )
+declare_pass( LoopDependenceAnalysis )
+declare_pass( LoopExtractor )
+declare_pass( LoopSimplify )
+declare_pass( LoopStrengthReduce )
+declare_pass( LowerInvoke )
+declare_pass( LowerSwitch )
+declare_pass( MergeFunctions )
+declare_pass( NoAA )
+declare_pass( NoProfileInfo )
+declare_pass( OptimalEdgeProfiler )
+declare_pass( PartialInlining )
+declare_pass( PostDomOnlyPrinter )
+declare_pass( PostDomOnlyViewer )
+declare_pass( PostDomPrinter )
+declare_pass( PostDomViewer )
+declare_pass( ProfileEstimator )
+declare_pass( ProfileLoader )
+declare_pass( ProfileVerifier )
+declare_pass( ScalarEvolutionAliasAnalysis )
+declare_pass( SingleLoopExtractor )
+declare_pass( StripNonDebugSymbols )
+declare_pass( StructRetPromotion )
+declare_pass( TailDuplication )
+declare_pass( UnifyFunctionExitNodes )
+
+declare_pass( Internalize2 )
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LLVM_PY_EXTRA_H */
+
diff --git a/include/support.h b/include/support.h
new file mode 100644
--- /dev/null
+++ b/include/support.h
@@ -0,0 +1,24 @@
+#ifndef LLVM_HS_SUPPORT_H
+#define LLVM_HS_SUPPORT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void LLVMCreateStandardFunctionPasses(LLVMPassManagerRef PM,
+				      unsigned OptimizationLevel);
+
+void LLVMCreateStandardModulePasses(LLVMPassManagerRef PM,
+				    unsigned OptimizationLevel,
+				    int OptimizeSize,
+				    int UnitAtATime,
+				    int UnrollLoops,
+				    int SimplifyLibCalls,
+				    int HaveExceptions,
+				    int DisableInlining);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* LLVM_HS_SUPPORT_H */
diff --git a/llvm-ffi.cabal b/llvm-ffi.cabal
new file mode 100644
--- /dev/null
+++ b/llvm-ffi.cabal
@@ -0,0 +1,149 @@
+Name:          llvm-ffi
+Version:       3.0.0
+License:       BSD3
+License-File:  LICENSE
+Synopsis:      FFI bindings to the LLVM compiler toolkit.
+Description:
+  FFI bindings to the LLVM compiler toolkit.
+  .
+  Installation is based on @pkg-config@
+  since this is best supported by Cabal.
+  This requires an @llvm.pc@ file
+  which unfortunately is not generated by the LLVM source package.
+  You may be lucky that your distribution package includes that file.
+  If not, you can generate it yourself
+  using the @llvm-pkg-config@ package.
+  .
+  We try to stay up to date with LLVM releases.
+  The current version of this package is compatible with LLVM 3.0.
+  Please understand that the package may or may not work
+  against older LLVM releases.
+  We don't have the time or resources to test across multiple releases.
+Author:        Henning Thielemann, Bryan O'Sullivan, Lennart Augustsson
+Maintainer:    Henning Thielemann <llvm@henning-thielemann.de>
+Homepage:      http://haskell.org/haskellwiki/LLVM
+Stability:     experimental
+Category:      Compilers/Interpreters, Code Generation
+Tested-With:   GHC==7.4.2, GHC==7.6.3, GHC==7.8.4, GHC==7.10.1
+Cabal-Version: >= 1.6
+Build-Type:    Simple
+
+Extra-Source-Files:
+  include/extra.h
+  include/support.h
+  tool/ltrace.config
+  tool/ltrace.readme
+
+Flag developer
+  Description: developer mode - warnings let compilation fail
+  Default: False
+
+Flag buildTools
+  Description: build tools for managing this package
+  Default: False
+
+Source-Repository head
+  Type:     darcs
+  Location: http://code.haskell.org/~thielema/llvm-ffi/
+
+Source-Repository this
+  Tag:      3.0.0
+  Type:     darcs
+  Location: http://code.haskell.org/~thielema/llvm-ffi/
+
+Library
+  Build-Depends:
+    base >= 3 && < 5
+
+  Hs-Source-Dirs: src
+  GHC-Options: -Wall -fwarn-missing-import-lists
+
+  If flag(developer)
+    GHC-Options: -Werror
+
+  Exposed-Modules:
+      LLVM.FFI.Analysis
+      LLVM.FFI.BitReader
+      LLVM.FFI.BitWriter
+      LLVM.FFI.Core
+      LLVM.FFI.ExecutionEngine
+      LLVM.FFI.Support
+      LLVM.FFI.Target
+      LLVM.FFI.Transforms.IPO
+      LLVM.FFI.Transforms.Scalar
+      LLVM.Target.Native
+
+  Other-modules:
+      LLVM.Target.ARM
+      LLVM.Target.Alpha
+      LLVM.Target.Blackfin
+      LLVM.Target.CBackend
+      LLVM.Target.CellSPU
+      LLVM.Target.CppBackend
+      LLVM.Target.MSP430
+      LLVM.Target.Mips
+      LLVM.Target.PowerPC
+      LLVM.Target.Sparc
+      LLVM.Target.SystemZ
+      LLVM.Target.X86
+      LLVM.Target.XCore
+
+  PkgConfig-Depends: llvm == 3.0
+  CC-Options: -DHS_LLVM_VERSION=300 -DHAVE_LLVM_SUPPORT_DYNAMICLIBRARY_H=1
+  CPP-Options: -DHS_LLVM_VERSION=300
+  CPP-Options: -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
+  Include-Dirs: include
+  C-Sources:
+    cbits/extra.cpp
+    cbits/support.cpp
+
+Executable llvm-diff-ffi
+  If flag(buildTools)
+    Build-Depends:
+      utility-ht >=0.0.9 && <0.1,
+      regex-posix >=0.95 && <0.96,
+      containers >=0.4 && <0.6,
+      base
+  Else
+    Buildable: False
+
+  If flag(developer)
+    GHC-Options: -Werror
+
+  Hs-Source-Dirs: tool
+  GHC-Options: -Wall
+  Main-Is: DiffFFI.hs
+  Other-Modules: FunctionMangulation
+
+Executable llvm-function-mangler
+  If flag(buildTools)
+    Build-Depends:
+      utility-ht >=0.0.9 && <0.1,
+      regex-posix >=0.95 && <0.96,
+      containers >=0.4 && <0.6,
+      base
+  Else
+    Buildable: False
+
+  If flag(developer)
+    GHC-Options: -Werror
+
+  Hs-Source-Dirs: tool
+  GHC-Options: -Wall
+  Main-Is: FunctionMangler.hs
+  Other-Modules: FunctionMangulation
+
+Executable llvm-intrinsic-mangler
+  If flag(buildTools)
+    Build-Depends:
+      bytestring >=0.9 && <0.11,
+      base
+  Else
+    Buildable: False
+
+  If flag(developer)
+    GHC-Options: -Werror
+
+  Hs-Source-Dirs: tool
+  GHC-Options: -Wall
+  Main-Is: IntrinsicMangler.hs
diff --git a/src/LLVM/FFI/Analysis.hsc b/src/LLVM/FFI/Analysis.hsc
new file mode 100644
--- /dev/null
+++ b/src/LLVM/FFI/Analysis.hsc
@@ -0,0 +1,25 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE EmptyDataDecls #-}
+
+module LLVM.FFI.Analysis where
+
+import LLVM.FFI.Core (ModuleRef, ValueRef)
+
+import qualified Foreign.C.Types as C
+import Foreign.C.String(CString)
+import Foreign.Ptr(Ptr)
+
+type CInt = C.CInt
+
+
+type VerifierFailureAction = CInt
+
+foreign import ccall unsafe "LLVMVerifyFunction" verifyFunction
+    :: ValueRef -> VerifierFailureAction -> IO CInt
+foreign import ccall unsafe "LLVMVerifyModule" verifyModule
+    :: ModuleRef -> VerifierFailureAction -> (Ptr CString) -> IO CInt
+foreign import ccall unsafe "LLVMViewFunctionCFG" viewFunctionCFG
+    :: ValueRef -> IO ()
+foreign import ccall unsafe "LLVMViewFunctionCFGOnly" viewFunctionCFGOnly
+    :: ValueRef -> IO ()
diff --git a/src/LLVM/FFI/BitReader.hsc b/src/LLVM/FFI/BitReader.hsc
new file mode 100644
--- /dev/null
+++ b/src/LLVM/FFI/BitReader.hsc
@@ -0,0 +1,27 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE EmptyDataDecls #-}
+
+module LLVM.FFI.BitReader where
+
+import LLVM.FFI.Core (MemoryBufferRef, ModuleRef, ContextRef, ModuleProviderRef)
+
+import qualified Foreign.C.Types as C
+import Foreign.C.String(CString)
+import Foreign.Ptr(Ptr)
+
+type CInt = C.CInt
+
+
+foreign import ccall unsafe "LLVMGetBitcodeModuleProvider" getBitcodeModuleProvider
+    :: MemoryBufferRef -> (Ptr ModuleProviderRef) -> (Ptr CString) -> IO CInt
+foreign import ccall unsafe "LLVMParseBitcode" parseBitcode
+    :: MemoryBufferRef -> (Ptr ModuleRef) -> (Ptr CString) -> IO CInt
+foreign import ccall unsafe "LLVMGetBitcodeModuleProviderInContext" getBitcodeModuleProviderInContext
+    :: ContextRef -> MemoryBufferRef -> (Ptr ModuleProviderRef) -> (Ptr CString) -> IO CInt
+foreign import ccall unsafe "LLVMParseBitcodeInContext" parseBitcodeInContext
+    :: ContextRef -> MemoryBufferRef -> (Ptr ModuleRef) -> (Ptr CString) -> IO CInt
+foreign import ccall unsafe "LLVMGetBitcodeModule" getBitcodeModule
+    :: MemoryBufferRef -> (Ptr ModuleRef) -> (Ptr CString) -> IO Bool
+foreign import ccall unsafe "LLVMGetBitcodeModuleInContext" getBitcodeModuleInContext
+    :: ContextRef -> MemoryBufferRef -> (Ptr ModuleRef) -> (Ptr CString) -> IO Bool
diff --git a/src/LLVM/FFI/BitWriter.hsc b/src/LLVM/FFI/BitWriter.hsc
new file mode 100644
--- /dev/null
+++ b/src/LLVM/FFI/BitWriter.hsc
@@ -0,0 +1,20 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE EmptyDataDecls #-}
+
+module LLVM.FFI.BitWriter where
+
+import LLVM.FFI.Core (ModuleRef)
+
+import qualified Foreign.C.Types as C
+import Foreign.C.String(CString)
+
+type CInt = C.CInt
+
+
+foreign import ccall unsafe "LLVMWriteBitcodeToFile" writeBitcodeToFile
+    :: ModuleRef -> CString -> IO CInt
+foreign import ccall unsafe "LLVMWriteBitcodeToFileHandle" writeBitcodeToFileHandle
+    :: ModuleRef -> CInt -> IO CInt
+foreign import ccall unsafe "LLVMWriteBitcodeToFD" writeBitcodeToFD
+    :: ModuleRef -> CInt -> CInt -> CInt -> IO CInt
diff --git a/src/LLVM/FFI/Core.hsc b/src/LLVM/FFI/Core.hsc
new file mode 100644
--- /dev/null
+++ b/src/LLVM/FFI/Core.hsc
@@ -0,0 +1,1743 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE EmptyDataDecls #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+
+-- |
+-- Module:      LLVM.FFI.Core
+-- Copyright:   Bryan O'Sullivan 2007, 2008
+-- License:     BSD-style (see the file LICENSE)
+--
+-- Maintainer:  bos@serpentine.com
+-- Stability:   experimental
+-- Portability: requires GHC 6.8, LLVM
+--
+-- This module provides direct access to the LLVM C bindings.
+
+module LLVM.FFI.Core
+    (
+      initializeCore
+
+    -- * Error handling
+    , disposeMessage
+
+    -- * Context functions
+    , Context
+    , ContextRef
+    , contextCreate
+    , contextDispose
+    , getGlobalContext
+
+    , getMDKindID
+    , getMDKindIDInContext
+
+      -- * Modules
+    , Module
+    , ModuleRef
+    , moduleCreateWithName
+    , moduleCreateWithNameInContext
+    , disposeModule
+    , ptrDisposeModule
+
+    , getDataLayout
+    , setDataLayout
+
+    , getTarget
+    , setTarget
+
+    , dumpModule
+
+    , setModuleInlineAsm
+    , getModuleContext
+
+    -- * Module providers
+    , ModuleProvider
+    , ModuleProviderRef
+    , createModuleProviderForExistingModule
+    , ptrDisposeModuleProvider
+
+    -- * Types
+    , Type
+    , TypeRef
+    , TypeKind(..)
+
+    , getTypeKind
+    , typeIsSized
+    , getTypeContext
+
+    -- ** Integer types
+    , int1TypeInContext
+    , int8TypeInContext
+    , int16TypeInContext
+    , int32TypeInContext
+    , int64TypeInContext
+    , intTypeInContext
+
+    , int1Type
+    , int8Type
+    , int16Type
+    , int32Type
+    , int64Type
+    , integerType
+    , getIntTypeWidth
+
+    -- ** Real types
+    , floatTypeInContext
+    , doubleTypeInContext
+    , x86FP80TypeInContext
+    , fP128TypeInContext
+    , pPCFP128TypeInContext
+
+    , floatType
+    , doubleType
+    , x86FP80Type
+    , fP128Type
+    , pPCFP128Type
+
+    -- ** Function types
+    , functionType
+    , isFunctionVarArg
+    , getReturnType
+    , countParamTypes
+    , getParamTypes
+
+    -- ** Struct types
+    , structTypeInContext
+    , structType
+    , structCreateNamed
+    , getStructName
+    , structSetBody
+
+    , countStructElementTypes
+    , getStructElementTypes
+    , isPackedStruct
+    , isOpaqueStruct
+
+    , getTypeByName
+
+    -- ** Array, pointer, and vector types
+    , arrayType
+    , pointerType
+    , vectorType
+
+    , getElementType
+    , getArrayLength
+    , getPointerAddressSpace
+    , getVectorSize
+
+    -- ** Other types
+    , voidTypeInContext
+    , labelTypeInContext
+    , x86MMXTypeInContext
+
+    , voidType
+    , labelType
+    , x86MMXType
+
+    -- * Values
+    , Value
+    , ValueRef
+    , typeOf
+    , getValueName
+    , setValueName
+    , dumpValue
+    , replaceAllUsesWith
+    , hasMetadata
+    , getMetadata
+    , setMetadata
+
+    -- ** Uses
+    , OpaqueUse
+    , UseRef
+    , getFirstUse
+    , getNextUse
+    , getUser
+    , getUsedValue
+
+    -- ** Users
+    , getOperand
+    , setOperand
+    , getNumOperands
+
+    -- ** Constants
+    , constNull
+    , constAllOnes
+    , getUndef
+    , isConstant
+    , isNull
+    , isUndef
+    , constPointerNull
+
+    -- ** Metadata
+    , mDStringInContext
+    , mDString
+    , mDNodeInContext
+    , mDNode
+    , getMDString
+--    , getMDNodeNumOperands
+--    , getMDNodeOperand
+    , getNamedMetadataNumOperands
+    , getNamedMetadataOperands
+
+    -- ** Scalar constants
+    , constInt
+    , constIntOfArbitraryPrecision
+    , constIntOfString
+    , constIntOfStringAndSize
+    , constReal
+    , constRealOfString
+    , constRealOfStringAndSize
+    , constIntGetZExtValue
+    , constIntGetSExtValue
+
+    -- ** Composite constants
+    , constStringInContext
+    , constStructInContext
+    , constString
+    , constArray
+    , constStruct
+    , constNamedStruct
+    , constVector
+
+    -- ** Constant Expressions
+    , getConstOpcode
+    , alignOf
+    , sizeOf
+    , constNeg
+    , constNUWNeg
+    , constNSWNeg
+    , constFNeg
+    , constNot
+    , constAdd
+    , constNSWAdd
+    , constNUWAdd
+    , constFAdd
+    , constSub
+    , constNSWSub
+    , constNUWSub
+    , constFSub
+    , constMul
+    , constNSWMul
+    , constNUWMul
+    , constFMul
+    , constUDiv
+    , constSDiv
+    , constExactSDiv
+    , constFDiv
+    , constURem
+    , constSRem
+    , constFRem
+    , constAnd
+    , constOr
+    , constXor
+    , constICmp
+    , constFCmp
+    , constShl
+    , constLShr
+    , constAShr
+    , constGEP
+    , constInBoundsGEP
+    , constTrunc
+    , constSExt
+    , constZExt
+    , constFPTrunc
+    , constFPExt
+    , constUIToFP
+    , constSIToFP
+    , constFPToUI
+    , constFPToSI
+    , constPtrToInt
+    , constIntToPtr
+    , constBitCast
+    , constZExtOrBitCast
+    , constSExtOrBitCast
+    , constTruncOrBitCast
+    , constPointerCast
+    , constIntCast
+    , constFPCast
+    , constSelect
+    , constExtractElement
+    , constInsertElement
+    , constShuffleVector
+    , constExtractValue
+    , constInsertValue
+    , constInlineAsm
+    , blockAddress
+
+    -- ** Support operations and types
+    , Linkage(..)
+    , fromLinkage
+    , toLinkage
+
+    , Visibility(..)
+    , fromVisibility
+    , toVisibility
+
+    -- ** Global variables, functions, and aliases (globals)
+    , getGlobalParent
+    , isDeclaration
+    , getLinkage
+    , setLinkage
+    , getSection
+    , setSection
+    , getVisibility
+    , setVisibility
+    , getAlignment
+    , setAlignment
+      
+    -- ** Global variables
+    , addGlobal
+    , addGlobalInAddressSpace
+    , getNamedGlobal
+    , getFirstGlobal
+    , getLastGlobal
+    , getNextGlobal
+    , getPreviousGlobal
+    , deleteGlobal
+    , getInitializer
+    , setInitializer
+    , isThreadLocal
+    , setThreadLocal
+    , isGlobalConstant
+    , setGlobalConstant
+
+    -- ** Aliases
+    , addAlias
+
+    -- * Parameter passing
+    , Attribute(..)
+    , fromAttribute
+    , toAttribute
+
+    -- ** Calling conventions
+    , CallingConvention(..)
+    , fromCallingConvention
+    , toCallingConvention
+
+    -- ** Functions
+    , addFunction
+    , getNamedFunction
+    , getFirstFunction
+    , getLastFunction
+    , getNextFunction
+    , getPreviousFunction
+    , deleteFunction
+    , getIntrinsicID
+    , getFunctionCallConv
+    , setFunctionCallConv
+    , getGC
+    , setGC
+    , addFunctionAttr
+    , getFunctionAttr
+    , removeFunctionAttr
+
+    -- ** Parameters
+    , countParams
+    , getParams
+    , getParam
+    , getParamParent
+    , getFirstParam
+    , getLastParam
+    , getNextParam
+    , getPreviousParam
+    , addAttribute
+    , removeAttribute
+    , getAttribute
+    , setParamAlignment
+
+    -- ** Basic blocks
+    , BasicBlock
+    , BasicBlockRef
+    , basicBlockAsValue
+    , valueIsBasicBlock
+    , valueAsBasicBlock
+    , getBasicBlockParent
+    , getBasicBlockTerminator
+    , countBasicBlocks
+    , getBasicBlocks
+    , getFirstBasicBlock
+    , getLastBasicBlock
+    , getNextBasicBlock
+    , getPreviousBasicBlock
+    , getEntryBasicBlock
+    , appendBasicBlockInContext
+    , insertBasicBlockInContext
+    , appendBasicBlock
+    , insertBasicBlock
+    , deleteBasicBlock
+    , removeBasicBlockFromParent
+    , moveBasicBlockBefore
+    , moveBasicBlockAfter
+    , getFirstInstruction
+    , getLastInstruction
+
+    -- ** Instructions
+    , getInstructionParent
+    , getNextInstruction
+    , getPreviousInstruction
+    , instructionEraseFromParent
+    , getInstructionOpcode
+    , getICmpPredicate
+
+    -- ** Call Sites
+    , getInstructionCallConv
+    , setInstructionCallConv
+    , addInstrAttribute
+    , removeInstrAttribute
+    , setInstrParamAlignment
+
+    -- ** Call Instructions (only)
+    , isTailCall
+    , setTailCall
+
+    -- ** Switch Instructions (only)
+    , getSwitchDefaultDest
+
+    -- ** Phi nodes
+    , addIncoming
+    , countIncoming
+    , getIncomingValue
+    , getIncomingBlock
+
+    -- * Instruction building
+    , Builder
+    , BuilderRef
+    , createBuilderInContext
+    , createBuilder
+    , positionBuilder
+    , positionBefore
+    , positionAtEnd
+    , getInsertBlock
+    , clearInsertionPosition
+    , insertIntoBuilder
+    , insertIntoBuilderWithName
+    , ptrDisposeBuilder
+
+    -- ** Metadata
+    , setCurrentDebugLocation
+    , getCurrentDebugLocation
+    , setInstDebugLocation
+
+    -- ** Terminators
+    , buildRetVoid
+    , buildRet
+    , buildAggregateRet
+    , buildBr
+    , buildCondBr
+    , buildSwitch
+    , buildIndirectBr
+    , buildInvoke
+    , buildLandingPad
+    , buildResume
+    , buildUnreachable
+
+    , addCase
+    , addDestination
+    , addClause
+    , setCleanup
+
+    -- ** Arithmetic
+    , buildAdd
+    , buildNSWAdd
+    , buildNUWAdd
+    , buildFAdd
+    , buildSub
+    , buildNSWSub
+    , buildNUWSub
+    , buildFSub
+    , buildMul
+    , buildNSWMul
+    , buildNUWMul
+    , buildFMul
+    , buildUDiv
+    , buildSDiv
+    , buildExactSDiv
+    , buildFDiv
+    , buildURem
+    , buildSRem
+    , buildFRem
+    , buildShl
+    , buildLShr
+    , buildAShr
+    , buildAnd
+    , buildOr
+    , buildXor
+    , buildBinOp
+    , buildNeg
+    , buildNSWNeg
+    , buildNUWNeg
+    , buildFNeg
+    , buildNot
+
+    -- ** Memory
+    , buildMalloc
+    , buildArrayMalloc
+    , buildAlloca
+    , buildArrayAlloca
+    , buildFree
+    , buildLoad
+    , buildStore
+    , buildGEP
+    , buildInBoundsGEP
+    , buildStructGEP
+    , buildGlobalString
+    , buildGlobalStringPtr
+
+    -- ** Casts
+    , buildTrunc
+    , buildZExt
+    , buildSExt
+    , buildFPToUI
+    , buildFPToSI
+    , buildUIToFP
+    , buildSIToFP
+    , buildFPTrunc
+    , buildFPExt
+    , buildPtrToInt
+    , buildIntToPtr
+    , buildBitCast
+    , buildZExtOrBitCast
+    , buildSExtOrBitCast
+    , buildTruncOrBitCast
+    , buildCast
+    , buildPointerCast
+    , buildIntCast
+    , buildFPCast
+
+    -- ** Comparisons
+    , buildICmp
+    , buildFCmp
+
+    -- ** Miscellaneous instructions
+    , buildPhi
+    , buildCall
+    , buildSelect
+    , buildVAArg
+    , buildExtractElement
+    , buildInsertElement
+    , buildShuffleVector
+    , buildExtractValue
+    , buildInsertValue
+    , buildIsNull
+    , buildIsNotNull
+    , buildPtrDiff
+
+    -- * Memory buffers
+    , MemoryBuffer
+    , MemoryBufferRef
+    , createMemoryBufferWithContentsOfFile
+    , createMemoryBufferWithSTDIN
+    , disposeMemoryBuffer
+
+    -- ** PassRegistry
+    , PassRegistry
+    , PassRegistryRef
+    , getGlobalPassRegistry
+
+    -- ** Pass manager
+    , PassManager
+    , PassManagerRef
+    , ptrDisposePassManager
+
+    , createPassManager
+    , createFunctionPassManagerForModule
+    , createFunctionPassManager
+    , runPassManager
+    , initializeFunctionPassManager
+    , runFunctionPassManager
+    , finalizeFunctionPassManager
+    , disposePassManager
+
+    -- ** Functions from extras.cpp
+    , getNumUses
+    , instGetOpcode
+    , cmpInstGetPredicate
+
+    ) where
+
+import qualified Foreign.C.Types as C
+import Foreign.C.String (CString)
+import Foreign.Ptr (Ptr, FunPtr)
+
+import Data.Typeable (Typeable)
+
+
+type CDouble  = C.CDouble
+type CInt     = C.CInt
+type CUInt    = C.CUInt
+type CLLong   = C.CLLong
+type CULLong  = C.CULLong
+
+
+#include <llvm-c/Core.h>
+
+data Module
+    deriving (Typeable)
+type ModuleRef = Ptr Module
+
+data ModuleProvider
+    deriving (Typeable)
+type ModuleProviderRef = Ptr ModuleProvider
+
+data Type
+    deriving (Typeable)
+type TypeRef = Ptr Type
+
+type BasicBlock = Value
+type BasicBlockRef = Ptr BasicBlock
+
+data Value
+    deriving (Typeable)
+type ValueRef = Ptr Value
+
+data OpaqueUse
+    deriving (Typeable)
+type UseRef = Ptr OpaqueUse
+
+data Builder
+    deriving (Typeable)
+type BuilderRef = Ptr Builder
+
+data MemoryBuffer
+    deriving (Typeable)
+type MemoryBufferRef = Ptr MemoryBuffer
+
+data PassManager
+    deriving (Typeable)
+type PassManagerRef = Ptr PassManager
+
+data PassRegistry
+    deriving (Typeable)
+type PassRegistryRef = Ptr PassRegistry
+
+data Context
+    deriving (Typeable)
+type ContextRef = Ptr Context
+
+data TypeKind
+    = VoidTypeKind
+    | FloatTypeKind
+    | DoubleTypeKind
+    | X86_FP80TypeKind
+    | FP128TypeKind
+    | PPC_FP128TypeKind
+    | LabelTypeKind
+    | IntegerTypeKind
+    | FunctionTypeKind
+    | StructTypeKind
+    | ArrayTypeKind
+    | PointerTypeKind
+    | OpaqueTypeKind
+    | VectorTypeKind
+    deriving (Eq, Ord, Enum, Bounded, Show, Read, Typeable)
+
+getTypeKind :: TypeRef -> IO TypeKind
+getTypeKind = fmap (toEnum . fromIntegral) . getTypeKindCUInt
+
+data CallingConvention = C
+                       | Fast
+                       | Cold
+                       | X86StdCall
+                       | X86FastCall
+                       | GHC
+                         deriving (Show, Eq, Ord, Enum, Bounded, Typeable)
+
+fromCallingConvention :: CallingConvention -> CUInt
+fromCallingConvention C = (#const LLVMCCallConv)
+fromCallingConvention Fast = (#const LLVMFastCallConv)
+fromCallingConvention Cold = (#const LLVMColdCallConv)
+fromCallingConvention X86StdCall = (#const LLVMX86FastcallCallConv)
+fromCallingConvention X86FastCall = (#const LLVMX86StdcallCallConv)
+fromCallingConvention GHC = 10
+
+toCallingConvention :: CUInt -> CallingConvention
+toCallingConvention c | c == (#const LLVMCCallConv) = C
+toCallingConvention c | c == (#const LLVMFastCallConv) = Fast
+toCallingConvention c | c == (#const LLVMColdCallConv) = Cold
+toCallingConvention c | c == (#const LLVMX86StdcallCallConv) = X86StdCall
+toCallingConvention c | c == (#const LLVMX86FastcallCallConv) = X86FastCall
+toCallingConvention c | c == 10 = GHC
+toCallingConvention c = error $ "LLVM.Core.FFI.toCallingConvention: " ++
+                                "unsupported calling convention" ++ show c
+
+-- |An enumeration for the kinds of linkage for global values.
+data Linkage
+    = ExternalLinkage     -- ^Externally visible function
+    | AvailableExternallyLinkage 
+    | LinkOnceAnyLinkage  -- ^Keep one copy of function when linking (inline)
+    | LinkOnceODRLinkage  -- ^Same, but only replaced by something equivalent.
+    | WeakAnyLinkage      -- ^Keep one copy of named function when linking (weak)
+    | WeakODRLinkage      -- ^Same, but only replaced by something equivalent.
+    | AppendingLinkage    -- ^Special purpose, only applies to global arrays
+    | InternalLinkage     -- ^Rename collisions when linking (static functions)
+    | PrivateLinkage      -- ^Like Internal, but omit from symbol table
+    | DLLImportLinkage    -- ^Function to be imported from DLL
+    | DLLExportLinkage    -- ^Function to be accessible from DLL
+    | ExternalWeakLinkage -- ^ExternalWeak linkage description
+    | GhostLinkage        -- ^Stand-in functions for streaming fns from BC files    
+    | CommonLinkage       -- ^Tentative definitions
+    | LinkerPrivateLinkage -- ^Like Private, but linker removes.
+    deriving (Show, Eq, Ord, Enum, Typeable)
+
+fromLinkage :: Linkage -> CUInt
+fromLinkage ExternalLinkage             = (#const LLVMExternalLinkage)
+fromLinkage AvailableExternallyLinkage  = (#const LLVMAvailableExternallyLinkage )
+fromLinkage LinkOnceAnyLinkage          = (#const LLVMLinkOnceAnyLinkage)
+fromLinkage LinkOnceODRLinkage          = (#const LLVMLinkOnceODRLinkage)
+fromLinkage WeakAnyLinkage              = (#const LLVMWeakAnyLinkage)
+fromLinkage WeakODRLinkage              = (#const LLVMWeakODRLinkage)
+fromLinkage AppendingLinkage            = (#const LLVMAppendingLinkage)
+fromLinkage InternalLinkage             = (#const LLVMInternalLinkage)
+fromLinkage PrivateLinkage              = (#const LLVMPrivateLinkage)
+fromLinkage DLLImportLinkage            = (#const LLVMDLLImportLinkage)
+fromLinkage DLLExportLinkage            = (#const LLVMDLLExportLinkage)
+fromLinkage ExternalWeakLinkage         = (#const LLVMExternalWeakLinkage)
+fromLinkage GhostLinkage                = (#const LLVMGhostLinkage)
+fromLinkage CommonLinkage               = (#const LLVMCommonLinkage)
+fromLinkage LinkerPrivateLinkage        = (#const LLVMLinkerPrivateLinkage)
+
+toLinkage :: CUInt -> Linkage
+toLinkage c | c == (#const LLVMExternalLinkage)             = ExternalLinkage
+toLinkage c | c == (#const LLVMAvailableExternallyLinkage)  = AvailableExternallyLinkage 
+toLinkage c | c == (#const LLVMLinkOnceAnyLinkage)          = LinkOnceAnyLinkage
+toLinkage c | c == (#const LLVMLinkOnceODRLinkage)          = LinkOnceODRLinkage
+toLinkage c | c == (#const LLVMWeakAnyLinkage)              = WeakAnyLinkage
+toLinkage c | c == (#const LLVMWeakODRLinkage)              = WeakODRLinkage
+toLinkage c | c == (#const LLVMAppendingLinkage)            = AppendingLinkage
+toLinkage c | c == (#const LLVMInternalLinkage)             = InternalLinkage
+toLinkage c | c == (#const LLVMPrivateLinkage)              = PrivateLinkage
+toLinkage c | c == (#const LLVMDLLImportLinkage)            = DLLImportLinkage
+toLinkage c | c == (#const LLVMDLLExportLinkage)            = DLLExportLinkage
+toLinkage c | c == (#const LLVMExternalWeakLinkage)         = ExternalWeakLinkage
+toLinkage c | c == (#const LLVMGhostLinkage)                = GhostLinkage
+toLinkage c | c == (#const LLVMCommonLinkage)               = CommonLinkage
+toLinkage c | c == (#const LLVMLinkerPrivateLinkage)        = LinkerPrivateLinkage
+toLinkage _ = error "toLinkage: bad value"
+
+-- |An enumeration for the kinds of visibility of global values.
+data Visibility
+    = DefaultVisibility   -- ^The GV is visible
+    | HiddenVisibility    -- ^The GV is hidden
+    | ProtectedVisibility -- ^The GV is protected
+    deriving (Show, Eq, Ord, Enum)
+
+fromVisibility :: Visibility -> CUInt
+fromVisibility DefaultVisibility   = (#const LLVMDefaultVisibility)
+fromVisibility HiddenVisibility    = (#const LLVMHiddenVisibility)
+fromVisibility ProtectedVisibility = (#const LLVMProtectedVisibility)
+
+toVisibility :: CUInt -> Visibility
+toVisibility c | c == (#const LLVMDefaultVisibility)   = DefaultVisibility
+toVisibility c | c == (#const LLVMHiddenVisibility)    = HiddenVisibility
+toVisibility c | c == (#const LLVMProtectedVisibility) = ProtectedVisibility
+toVisibility _ = error "toVisibility: bad value"
+
+data Attribute
+    = ZExtAttribute
+    | SExtAttribute
+    | NoReturnAttribute
+    | InRegAttribute
+    | StructRetAttribute
+    | NoUnwindAttribute
+    | NoAliasAttribute
+    | ByValAttribute
+    | NestAttribute
+    | ReadNoneAttribute
+    | ReadOnlyAttribute
+    | NoInlineAttribute
+    | AlwaysInlineAttribute
+    | OptimizeForSizeAttribute
+    | StackProtectAttribute
+    | StackProtectReqAttribute
+    | NoCaptureAttribute
+    | NoRedZoneAttribute
+    | NoImplicitFloatAttribute
+    | NakedAttribute
+    deriving (Show, Eq, Ord, Enum, Bounded, Typeable)
+
+fromAttribute :: Attribute -> CAttribute
+fromAttribute ZExtAttribute = (#const LLVMZExtAttribute)
+fromAttribute SExtAttribute = (#const LLVMSExtAttribute)
+fromAttribute NoReturnAttribute = (#const LLVMNoReturnAttribute)
+fromAttribute InRegAttribute = (#const LLVMInRegAttribute)
+fromAttribute StructRetAttribute = (#const LLVMStructRetAttribute)
+fromAttribute NoUnwindAttribute = (#const LLVMNoUnwindAttribute)
+fromAttribute NoAliasAttribute = (#const LLVMNoAliasAttribute)
+fromAttribute ByValAttribute = (#const LLVMByValAttribute)
+fromAttribute NestAttribute = (#const LLVMNestAttribute)
+fromAttribute ReadNoneAttribute = (#const LLVMReadNoneAttribute)
+fromAttribute ReadOnlyAttribute = (#const LLVMReadOnlyAttribute)
+fromAttribute NoInlineAttribute = (#const LLVMNoInlineAttribute)
+fromAttribute AlwaysInlineAttribute = (#const LLVMAlwaysInlineAttribute)
+fromAttribute OptimizeForSizeAttribute = (#const LLVMOptimizeForSizeAttribute)
+fromAttribute StackProtectAttribute = (#const LLVMStackProtectAttribute)
+fromAttribute StackProtectReqAttribute = (#const LLVMStackProtectReqAttribute)
+fromAttribute NoCaptureAttribute = (#const LLVMNoCaptureAttribute)
+fromAttribute NoRedZoneAttribute = (#const LLVMNoRedZoneAttribute)
+fromAttribute NoImplicitFloatAttribute = (#const LLVMNoImplicitFloatAttribute)
+fromAttribute NakedAttribute = (#const LLVMNakedAttribute)
+
+toAttribute :: CAttribute -> Attribute
+toAttribute c | c == (#const LLVMZExtAttribute) = ZExtAttribute
+toAttribute c | c == (#const LLVMSExtAttribute) = SExtAttribute
+toAttribute c | c == (#const LLVMNoReturnAttribute) = NoReturnAttribute
+toAttribute c | c == (#const LLVMInRegAttribute) = InRegAttribute
+toAttribute c | c == (#const LLVMStructRetAttribute) = StructRetAttribute
+toAttribute c | c == (#const LLVMNoUnwindAttribute) = NoUnwindAttribute
+toAttribute c | c == (#const LLVMNoAliasAttribute) = NoAliasAttribute
+toAttribute c | c == (#const LLVMByValAttribute) = ByValAttribute
+toAttribute c | c == (#const LLVMNestAttribute) = NestAttribute
+toAttribute c | c == (#const LLVMReadNoneAttribute) = ReadNoneAttribute
+toAttribute c | c == (#const LLVMReadOnlyAttribute) = ReadOnlyAttribute
+toAttribute c | c == (#const LLVMNoInlineAttribute) = NoInlineAttribute
+toAttribute c | c == (#const LLVMAlwaysInlineAttribute) = AlwaysInlineAttribute
+toAttribute c | c == (#const LLVMOptimizeForSizeAttribute) = OptimizeForSizeAttribute
+toAttribute c | c == (#const LLVMStackProtectAttribute) = StackProtectAttribute
+toAttribute c | c == (#const LLVMStackProtectReqAttribute) = StackProtectReqAttribute
+toAttribute c | c == (#const LLVMNoCaptureAttribute) = NoCaptureAttribute
+toAttribute c | c == (#const LLVMNoRedZoneAttribute) = NoRedZoneAttribute
+toAttribute c | c == (#const LLVMNoImplicitFloatAttribute) = NoImplicitFloatAttribute
+toAttribute c | c == (#const LLVMNakedAttribute) = NakedAttribute
+toAttribute _ = error "toAttribute: bad value"
+
+type CAttribute = CInt
+
+-- ** Initialization
+foreign import ccall unsafe "LLVMInitializeCore" initializeCore
+    :: PassRegistryRef -> IO ()
+
+-- ** Error Handling
+foreign import ccall unsafe "LLVMDisposeMessage" disposeMessage
+    :: CString -> IO ()
+
+-- ** Contexts
+foreign import ccall unsafe "LLVMContextCreate" contextCreate
+    :: IO ContextRef
+foreign import ccall unsafe "LLVMGetGlobalContext" getGlobalContext
+    :: IO ContextRef
+foreign import ccall unsafe "LLVMContextDispose" contextDispose
+    :: ContextRef -> IO ()
+foreign import ccall unsafe "LLVMGetMDKindIDInContext" getMDKindIDInContext
+    :: ContextRef -> CString -> CUInt -> IO CUInt
+foreign import ccall unsafe "LLVMGetMDKindID" getMDKindID
+    :: CString -> CUInt -> IO CUInt
+
+
+-- ** Modules
+foreign import ccall unsafe "LLVMModuleCreateWithName" moduleCreateWithName
+    :: CString -> IO ModuleRef
+foreign import ccall unsafe "LLVMModuleCreateWithNameInContext"
+        moduleCreateWithNameInContext
+    :: CString -> IO ModuleRef
+foreign import ccall unsafe "LLVMDisposeModule" disposeModule
+    :: ModuleRef -> IO ()
+foreign import ccall unsafe "&LLVMDisposeModule" ptrDisposeModule
+    :: FunPtr (ModuleRef -> IO ())
+
+-- ** Data Layout
+foreign import ccall unsafe "LLVMGetDataLayout" getDataLayout
+    :: ModuleRef -> IO CString
+foreign import ccall unsafe "LLVMSetDataLayout" setDataLayout
+    :: ModuleRef -> CString -> IO ()
+
+-- ** Targets
+foreign import ccall unsafe "LLVMGetTarget" getTarget
+    :: ModuleRef -> IO CString
+foreign import ccall unsafe "LLVMSetTarget" setTarget
+    :: ModuleRef -> CString -> IO ()
+
+-- ** Dump module
+foreign import ccall unsafe "LLVMDumpModule" dumpModule
+    :: ModuleRef -> IO ()
+foreign import ccall unsafe "LLVMSetModuleInlineAsm" setModuleInlineAsm
+    :: ModuleRef -> CString -> IO ()
+foreign import ccall unsafe "LLVMGetModuleContext" getModuleContext
+    :: ModuleRef -> IO ContextRef
+
+
+-- ** Types
+foreign import ccall unsafe "LLVMGetTypeKind" getTypeKindCUInt
+    :: TypeRef -> IO CUInt
+foreign import ccall unsafe "LLVMTypeIsSized" typeIsSized
+    :: TypeRef -> IO CInt
+foreign import ccall unsafe "LLVMGetTypeContext" getTypeContext
+    :: TypeRef -> IO ContextRef
+
+-- ** Integer types
+foreign import ccall unsafe "LLVMInt1TypeInContext" int1TypeInContext
+    :: ContextRef -> IO TypeRef
+foreign import ccall unsafe "LLVMInt8TypeInContext" int8TypeInContext
+    :: ContextRef -> IO TypeRef
+foreign import ccall unsafe "LLVMInt16TypeInContext" int16TypeInContext
+    :: ContextRef -> IO TypeRef
+foreign import ccall unsafe "LLVMInt32TypeInContext" int32TypeInContext
+    :: ContextRef -> IO TypeRef
+foreign import ccall unsafe "LLVMInt64TypeInContext" int64TypeInContext
+    :: ContextRef -> IO TypeRef
+foreign import ccall unsafe "LLVMIntTypeInContext" intTypeInContext
+    :: ContextRef -> CUInt -> IO TypeRef
+
+foreign import ccall unsafe "LLVMInt1Type" int1Type :: IO TypeRef
+foreign import ccall unsafe "LLVMInt8Type" int8Type :: IO TypeRef
+foreign import ccall unsafe "LLVMInt16Type" int16Type :: IO TypeRef
+foreign import ccall unsafe "LLVMInt32Type" int32Type :: IO TypeRef
+foreign import ccall unsafe "LLVMInt64Type" int64Type :: IO TypeRef
+foreign import ccall unsafe "LLVMIntType" integerType :: CUInt -> IO TypeRef
+foreign import ccall unsafe "LLVMGetIntTypeWidth" getIntTypeWidth
+    :: TypeRef -> IO CUInt
+
+-- ** Real types
+foreign import ccall unsafe "LLVMFloatTypeInContext" floatTypeInContext
+    :: ContextRef -> IO TypeRef
+foreign import ccall unsafe "LLVMDoubleTypeInContext" doubleTypeInContext
+    :: ContextRef -> IO TypeRef
+foreign import ccall unsafe "LLVMX86FP80TypeInContext" x86FP80TypeInContext
+    :: ContextRef -> IO TypeRef
+foreign import ccall unsafe "LLVMFP128TypeInContext" fP128TypeInContext
+    :: ContextRef -> IO TypeRef
+foreign import ccall unsafe "LLVMPPCFP128TypeInContext" pPCFP128TypeInContext
+    :: ContextRef -> IO TypeRef
+
+foreign import ccall unsafe "LLVMFloatType" floatType :: IO TypeRef
+foreign import ccall unsafe "LLVMDoubleType" doubleType :: IO TypeRef
+foreign import ccall unsafe "LLVMX86FP80Type" x86FP80Type :: IO TypeRef
+foreign import ccall unsafe "LLVMFP128Type" fP128Type :: IO TypeRef
+foreign import ccall unsafe "LLVMPPCFP128Type" pPCFP128Type :: IO TypeRef
+
+-- ** Function types
+-- | Create a function type.
+foreign import ccall unsafe "LLVMFunctionType" functionType
+        :: TypeRef              -- ^ return type
+        -> Ptr TypeRef          -- ^ array of argument types
+        -> CUInt                -- ^ number of elements in array
+        -> CInt                 -- ^ non-zero if function is varargs
+        -> IO TypeRef
+
+-- | Indicate whether a function takes varargs.
+foreign import ccall unsafe "LLVMIsFunctionVarArg" isFunctionVarArg
+        :: TypeRef -> IO CInt
+
+-- | Give a function's return type.
+foreign import ccall unsafe "LLVMGetReturnType" getReturnType
+        :: TypeRef -> IO TypeRef
+
+-- | Give the number of fixed parameters that a function takes.
+foreign import ccall unsafe "LLVMCountParamTypes" countParamTypes
+        :: TypeRef -> IO CUInt
+
+-- | Fill out an array with the types of a function's fixed
+-- parameters.
+foreign import ccall unsafe "LLVMGetParamTypes" getParamTypes
+        :: TypeRef -> Ptr TypeRef -> IO ()
+
+-- ** Struct Type
+foreign import ccall unsafe "LLVMStructTypeInContext" structTypeInContext
+    :: ContextRef -> (Ptr TypeRef) -> CUInt -> CInt -> IO TypeRef
+foreign import ccall unsafe "LLVMStructType" structType
+    :: Ptr TypeRef -> CUInt -> CInt -> IO TypeRef
+foreign import ccall unsafe "LLVMStructCreateNamed" structCreateNamed
+    :: ContextRef -> CString -> IO TypeRef
+foreign import ccall unsafe "LLVMGetStructName" getStructName
+    :: TypeRef -> IO CString
+foreign import ccall unsafe "LLVMStructSetBody" structSetBody
+    :: TypeRef -> Ptr TypeRef -> CUInt -> CInt -> IO ()
+foreign import ccall unsafe "LLVMCountStructElementTypes"
+    countStructElementTypes :: TypeRef -> IO CUInt
+foreign import ccall unsafe "LLVMGetStructElementTypes" getStructElementTypes
+    :: TypeRef -> Ptr TypeRef -> IO ()
+foreign import ccall unsafe "LLVMIsPackedStruct" isPackedStruct
+    :: TypeRef -> IO CInt
+foreign import ccall unsafe "LLVMIsOpaqueStruct" isOpaqueStruct
+    :: TypeRef -> IO CInt
+foreign import ccall unsafe "LLVMGetTypeByName" getTypeByName
+    :: ModuleRef -> CString -> IO TypeRef
+
+-- ** Array, Pointer, and Vector types
+foreign import ccall unsafe "LLVMArrayType" arrayType
+    :: TypeRef                  -- ^ element type
+    -> CUInt                    -- ^ element count
+    -> IO TypeRef
+foreign import ccall unsafe "LLVMPointerType" pointerType
+    :: TypeRef                  -- ^ pointed-to type
+    -> CUInt                    -- ^ address space
+    -> IO TypeRef
+foreign import ccall unsafe "LLVMVectorType" vectorType
+    :: TypeRef                  -- ^ element type
+    -> CUInt                    -- ^ element count
+    -> IO TypeRef
+
+
+-- | Get the type of a sequential type's elements.
+foreign import ccall unsafe "LLVMGetElementType" getElementType
+    :: TypeRef -> IO TypeRef
+foreign import ccall unsafe "LLVMGetArrayLength" getArrayLength
+    :: TypeRef -> IO CUInt
+foreign import ccall unsafe "LLVMGetPointerAddressSpace" getPointerAddressSpace
+    :: TypeRef -> IO CUInt
+foreign import ccall unsafe "LLVMGetVectorSize" getVectorSize
+    :: TypeRef -> IO CUInt
+
+
+-- ** Other Types
+
+foreign import ccall unsafe "LLVMVoidTypeInContext" voidTypeInContext
+    :: ContextRef -> IO TypeRef
+foreign import ccall unsafe "LLVMLabelTypeInContext" labelTypeInContext
+    :: ContextRef -> IO TypeRef
+foreign import ccall unsafe "LLVMX86MMXTypeInContext" x86MMXTypeInContext
+    :: ContextRef -> IO TypeRef
+
+foreign import ccall unsafe "LLVMVoidType" voidType :: IO TypeRef
+foreign import ccall unsafe "LLVMLabelType" labelType :: IO TypeRef
+foreign import ccall unsafe "LLVMX86MMXType" x86MMXType :: IO TypeRef
+
+-- ** Values
+foreign import ccall unsafe "LLVMTypeOf" typeOf
+    :: ValueRef -> IO TypeRef
+foreign import ccall unsafe "LLVMGetValueName" getValueName
+    :: ValueRef -> IO CString
+foreign import ccall unsafe "LLVMSetValueName" setValueName
+    :: ValueRef -> CString -> IO ()
+foreign import ccall unsafe "LLVMDumpValue" dumpValue
+    :: ValueRef -> IO ()
+foreign import ccall unsafe "LLVMReplaceAllUsesWith" replaceAllUsesWith
+    :: ValueRef -> ValueRef -> IO ()
+foreign import ccall unsafe "LLVMHasMetadata" hasMetadata
+    :: ValueRef -> IO CInt
+foreign import ccall unsafe "LLVMGetMetadata" getMetadata
+    :: ValueRef -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMSetMetadata" setMetadata
+    :: ValueRef -> CUInt -> ValueRef -> IO ()
+
+-- ** Uses
+foreign import ccall unsafe "LLVMGetFirstUse" getFirstUse
+    :: ValueRef -> IO UseRef
+foreign import ccall unsafe "LLVMGetNextUse" getNextUse
+    :: UseRef -> IO UseRef
+foreign import ccall unsafe "LLVMGetUser" getUser
+    :: UseRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetUsedValue" getUsedValue
+    :: UseRef -> IO ValueRef
+
+-- ** Users
+foreign import ccall unsafe "LLVMGetOperand" getOperand
+    :: ValueRef -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMSetOperand" setOperand
+    :: ValueRef -> CUInt -> ValueRef -> IO ()
+foreign import ccall unsafe "LLVMGetNumOperands" getNumOperands
+    :: ValueRef -> IO CUInt
+
+-- ** Constants
+foreign import ccall unsafe "LLVMConstNull" constNull
+    :: TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstAllOnes" constAllOnes
+    :: TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetUndef" getUndef
+    :: TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMIsConstant" isConstant
+    :: ValueRef -> IO CInt
+foreign import ccall unsafe "LLVMIsUndef" isUndef
+    :: ValueRef -> IO CInt
+foreign import ccall unsafe "LLVMIsNull" isNull
+    :: ValueRef -> IO CInt
+foreign import ccall unsafe "LLVMConstPointerNull" constPointerNull
+    :: TypeRef -> IO ValueRef
+
+-- ** Metadata
+foreign import ccall unsafe "LLVMMDStringInContext" mDStringInContext
+    :: ContextRef -> CString -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMMDString" mDString
+    :: CString -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMMDNodeInContext" mDNodeInContext
+    :: ContextRef -> (Ptr ValueRef) -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMMDNode" mDNode
+    :: (Ptr ValueRef) -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMGetMDString" getMDString
+    :: ValueRef -> Ptr CUInt -> IO CString
+{-
+foreign import ccall unsafe "LLVMGetMDNodeNumOperands" getMDNodeNumOperands
+    :: ValueRef -> IO (CInt)
+foreign import ccall unsafe "LLVMGetMDNodeOperand" getMDNodeOperand
+    :: ValueRef -> CUInt -> IO (Ptr ValueRef)
+-}
+foreign import ccall unsafe "LLVMGetNamedMetadataNumOperands" getNamedMetadataNumOperands
+    :: ModuleRef -> CString -> IO CUInt
+foreign import ccall unsafe "LLVMGetNamedMetadataOperands" getNamedMetadataOperands
+    :: ModuleRef -> CString -> Ptr ValueRef -> IO ()
+
+-- ** Scalar Constants
+foreign import ccall unsafe "LLVMConstInt" constInt
+    :: TypeRef -> CULLong -> CInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstIntOfArbitraryPrecision" constIntOfArbitraryPrecision
+    :: TypeRef -> CUInt -> Ptr CULLong -> IO ValueRef
+foreign import ccall unsafe "LLVMConstIntOfString" constIntOfString
+    :: TypeRef -> CString -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstIntOfStringAndSize" constIntOfStringAndSize
+    :: TypeRef -> CString -> CUInt -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstReal" constReal
+    :: TypeRef -> CDouble -> IO ValueRef
+foreign import ccall unsafe "LLVMConstRealOfString" constRealOfString
+    :: TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMConstRealOfStringAndSize" constRealOfStringAndSize
+    :: TypeRef -> CString -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstIntGetZExtValue" constIntGetZExtValue
+    :: ValueRef -> IO CULLong
+foreign import ccall unsafe "LLVMConstIntGetSExtValue" constIntGetSExtValue
+    :: ValueRef -> IO CLLong
+
+-- ** Composite Constants
+foreign import ccall unsafe "LLVMConstStringInContext" constStringInContext
+    :: ContextRef -> CString -> CUInt -> CInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstStructInContext" constStructInContext
+    :: ContextRef -> (Ptr ValueRef) -> CUInt -> CInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstString" constString
+    :: CString -> CUInt -> CInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstArray" constArray
+    :: TypeRef -> Ptr ValueRef -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstStruct" constStruct
+    :: Ptr ValueRef -> CUInt -> CInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstNamedStruct" constNamedStruct
+    :: TypeRef -> Ptr ValueRef -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstVector" constVector
+    :: Ptr ValueRef -> CUInt -> IO ValueRef
+
+-- ** Constant expressions
+foreign import ccall unsafe "LLVMGetConstOpcode" getConstOpcode
+    :: ValueRef -> IO CUInt {-Opcode-}
+foreign import ccall unsafe "LLVMAlignOf" alignOf
+    :: TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMSizeOf" sizeOf
+    :: TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstNeg" constNeg
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstNSWNeg" constNSWNeg
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstNUWNeg" constNUWNeg
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstFNeg" constFNeg
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstNot" constNot
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstAdd" constAdd
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstNSWAdd" constNSWAdd
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstNUWAdd" constNUWAdd
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstFAdd" constFAdd
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstSub" constSub
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstNSWSub" constNSWSub
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstNUWSub" constNUWSub
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstFSub" constFSub
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstMul" constMul
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstNSWMul" constNSWMul
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstNUWMul" constNUWMul
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstFMul" constFMul
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstUDiv" constUDiv
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstSDiv" constSDiv
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstExactSDiv" constExactSDiv
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstFDiv" constFDiv
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstURem" constURem
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstSRem" constSRem
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstFRem" constFRem
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstAnd" constAnd
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstOr" constOr
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstXor" constXor
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstICmp" constICmp
+    :: CInt -> ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstFCmp" constFCmp
+    :: CInt -> ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstShl" constShl
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstLShr" constLShr
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstAShr" constAShr
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstGEP" constGEP
+    :: ValueRef -> Ptr ValueRef -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstInBoundsGEP" constInBoundsGEP
+    :: ValueRef -> (Ptr ValueRef) -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstTrunc" constTrunc
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstSExt" constSExt
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstZExt" constZExt
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstFPTrunc" constFPTrunc
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstFPExt" constFPExt
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstUIToFP" constUIToFP
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstSIToFP" constSIToFP
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstFPToUI" constFPToUI
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstFPToSI" constFPToSI
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstPtrToInt" constPtrToInt
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstIntToPtr" constIntToPtr
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstBitCast" constBitCast
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstSExtOrBitCast" constSExtOrBitCast
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstZExtOrBitCast" constZExtOrBitCast
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstTruncOrBitCast" constTruncOrBitCast
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstPointerCast" constPointerCast
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstIntCast" constIntCast
+    :: ValueRef -> TypeRef -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstFPCast" constFPCast
+    :: ValueRef -> TypeRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstSelect" constSelect
+    :: ValueRef -> ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstExtractElement" constExtractElement
+    :: ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstInsertElement" constInsertElement
+    :: ValueRef -> ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstShuffleVector" constShuffleVector
+    :: ValueRef -> ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMConstExtractValue" constExtractValue
+    :: ValueRef -> Ptr CUInt -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstInsertValue" constInsertValue
+    :: ValueRef -> ValueRef -> Ptr CUInt -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMConstInlineAsm" constInlineAsm
+    :: TypeRef -> CString -> CString -> Bool -> Bool -> IO ValueRef
+foreign import ccall unsafe "LLVMBlockAddress" blockAddress
+    :: ValueRef -> BasicBlockRef -> IO ValueRef
+
+-- ** Operations on globals
+foreign import ccall unsafe "LLVMGetGlobalParent" getGlobalParent
+    :: ValueRef -> IO ModuleRef
+foreign import ccall unsafe "LLVMIsDeclaration" isDeclaration
+    :: ValueRef -> IO CInt
+foreign import ccall unsafe "LLVMGetLinkage" getLinkage
+    :: ValueRef -> IO CUInt
+foreign import ccall unsafe "LLVMSetLinkage" setLinkage
+    :: ValueRef -> CUInt -> IO ()
+foreign import ccall unsafe "LLVMGetSection" getSection
+    :: ValueRef -> IO CString
+foreign import ccall unsafe "LLVMSetSection" setSection
+    :: ValueRef -> CString -> IO ()
+foreign import ccall unsafe "LLVMGetVisibility" getVisibility
+    :: ValueRef -> IO CUInt
+foreign import ccall unsafe "LLVMSetVisibility" setVisibility
+    :: ValueRef -> CUInt -> IO ()
+foreign import ccall unsafe "LLVMGetAlignment" getAlignment
+    :: ValueRef -> IO CUInt
+foreign import ccall unsafe "LLVMSetAlignment" setAlignment
+    :: ValueRef -> CUInt -> IO ()
+
+-- ** Global Variables
+foreign import ccall unsafe "LLVMAddGlobal" addGlobal
+    :: ModuleRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMAddGlobalInAddressSpace" addGlobalInAddressSpace
+    :: ModuleRef -> TypeRef -> CString -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMGetNamedGlobal" getNamedGlobal
+    :: ModuleRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMGetFirstGlobal" getFirstGlobal
+    :: ModuleRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetLastGlobal" getLastGlobal
+    :: ModuleRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetNextGlobal" getNextGlobal
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetPreviousGlobal" getPreviousGlobal
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMDeleteGlobal" deleteGlobal
+    :: ValueRef -> IO ()
+foreign import ccall unsafe "LLVMSetInitializer" setInitializer
+    :: ValueRef -> ValueRef -> IO ()
+foreign import ccall unsafe "LLVMGetInitializer" getInitializer
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMIsThreadLocal" isThreadLocal
+    :: ValueRef -> IO CInt
+foreign import ccall unsafe "LLVMSetThreadLocal" setThreadLocal
+    :: ValueRef -> CInt -> IO ()
+foreign import ccall unsafe "LLVMIsGlobalConstant" isGlobalConstant
+    :: ValueRef -> IO CInt
+foreign import ccall unsafe "LLVMSetGlobalConstant" setGlobalConstant
+    :: ValueRef -> CInt -> IO ()
+
+-- ** Aliases
+foreign import ccall unsafe "LLVMAddAlias" addAlias
+    :: ModuleRef -> TypeRef -> ValueRef -> CString -> IO ValueRef
+
+-- ** Functions
+foreign import ccall unsafe "LLVMAddFunction" addFunction
+    :: ModuleRef                -- ^ module
+    -> CString                  -- ^ name
+    -> TypeRef                  -- ^ type
+    -> IO ValueRef
+foreign import ccall unsafe "LLVMGetNamedFunction" getNamedFunction
+    :: ModuleRef                -- ^ module
+    -> CString                  -- ^ name
+    -> IO ValueRef              -- ^ function (@nullPtr@ if not found)
+foreign import ccall unsafe "LLVMGetFirstFunction" getFirstFunction
+    :: ModuleRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetLastFunction" getLastFunction
+    :: ModuleRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetNextFunction" getNextFunction
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetPreviousFunction" getPreviousFunction
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMDeleteFunction" deleteFunction
+    :: ValueRef                 -- ^ function
+    -> IO ()
+foreign import ccall unsafe "LLVMGetIntrinsicID" getIntrinsicID
+    :: ValueRef                 -- ^ function
+    -> IO CUInt
+foreign import ccall unsafe "LLVMGetFunctionCallConv" getFunctionCallConv
+    :: ValueRef                 -- ^ function
+    -> IO CUInt
+foreign import ccall unsafe "LLVMSetFunctionCallConv" setFunctionCallConv
+    :: ValueRef                 -- ^ function
+    -> CUInt
+    -> IO ()
+foreign import ccall unsafe "LLVMGetGC" getGC
+    :: ValueRef -> IO CString
+foreign import ccall unsafe "LLVMSetGC" setGC
+    :: ValueRef -> CString -> IO ()
+foreign import ccall unsafe "LLVMGetFunctionAttr" getFunctionAttr
+    :: ValueRef -> IO CUInt {-Attribute-}
+foreign import ccall unsafe "LLVMAddFunctionAttr" addFunctionAttr
+    :: ValueRef -> CAttribute -> IO ()
+foreign import ccall unsafe "LLVMRemoveFunctionAttr" removeFunctionAttr
+    :: ValueRef -> CAttribute -> IO ()
+
+-- ** Parameters
+foreign import ccall unsafe "LLVMCountParams" countParams
+    :: ValueRef                 -- ^ function
+    -> IO CUInt
+foreign import ccall unsafe "LLVMGetParams" getParams
+    :: ValueRef                 -- ^ function
+    -> Ptr ValueRef             -- ^ array to fill out
+    -> IO ()
+foreign import ccall unsafe "LLVMGetParam" getParam
+    :: ValueRef                 -- ^ function
+    -> CUInt                    -- ^ offset into array
+    -> IO ValueRef
+foreign import ccall unsafe "LLVMGetParamParent" getParamParent
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetFirstParam" getFirstParam
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetLastParam" getLastParam
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetNextParam" getNextParam
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetPreviousParam" getPreviousParam
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMAddAttribute" addAttribute
+    :: ValueRef -> CAttribute -> IO ()
+foreign import ccall unsafe "LLVMRemoveAttribute" removeAttribute
+    :: ValueRef -> CAttribute -> IO ()
+foreign import ccall unsafe "LLVMGetAttribute" getAttribute
+    :: ValueRef -> IO CUInt{-Attribute-}
+foreign import ccall unsafe "LLVMSetParamAlignment" setParamAlignment
+    :: ValueRef -> CUInt -> IO ()
+
+-- ** Basic Blocks
+foreign import ccall unsafe "LLVMBasicBlockAsValue" basicBlockAsValue
+    :: BasicBlockRef -> IO ValueRef
+foreign import ccall unsafe "LLVMValueIsBasicBlock" valueIsBasicBlock
+    :: ValueRef -> IO Bool
+foreign import ccall unsafe "LLVMValueAsBasicBlock" valueAsBasicBlock
+    :: ValueRef                 -- ^ basic block
+    -> IO BasicBlockRef
+foreign import ccall unsafe "LLVMGetBasicBlockParent" getBasicBlockParent
+    :: BasicBlockRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetBasicBlockTerminator" getBasicBlockTerminator
+    :: BasicBlockRef -> IO ValueRef
+foreign import ccall unsafe "LLVMCountBasicBlocks" countBasicBlocks
+    :: ValueRef                 -- ^ function
+    -> IO CUInt
+foreign import ccall unsafe "LLVMGetBasicBlocks" getBasicBlocks
+    :: ValueRef                 -- ^ function
+    -> Ptr BasicBlockRef        -- ^ array to fill out
+    -> IO ()
+foreign import ccall unsafe "LLVMGetFirstBasicBlock" getFirstBasicBlock
+    :: ValueRef -> IO BasicBlockRef
+foreign import ccall unsafe "LLVMGetLastBasicBlock" getLastBasicBlock
+    :: ValueRef -> IO BasicBlockRef
+foreign import ccall unsafe "LLVMGetNextBasicBlock" getNextBasicBlock
+    :: BasicBlockRef -> IO BasicBlockRef
+foreign import ccall unsafe "LLVMGetPreviousBasicBlock" getPreviousBasicBlock
+    :: BasicBlockRef -> IO BasicBlockRef
+foreign import ccall unsafe "LLVMGetEntryBasicBlock" getEntryBasicBlock
+    :: ValueRef                 -- ^ function
+    -> IO BasicBlockRef
+foreign import ccall unsafe "LLVMAppendBasicBlockInContext" appendBasicBlockInContext
+    :: ContextRef -> ValueRef -> CString -> IO BasicBlockRef
+foreign import ccall unsafe "LLVMInsertBasicBlockInContext" insertBasicBlockInContext
+    :: ContextRef -> BasicBlockRef -> CString -> IO BasicBlockRef
+foreign import ccall unsafe "LLVMAppendBasicBlock" appendBasicBlock
+    :: ValueRef                 -- ^ function
+    -> CString                  -- ^ name for label
+    -> IO BasicBlockRef
+foreign import ccall unsafe "LLVMInsertBasicBlock" insertBasicBlock
+    :: BasicBlockRef            -- ^ insert before this one
+    -> CString                  -- ^ name for label
+    -> IO BasicBlockRef
+foreign import ccall unsafe "LLVMDeleteBasicBlock" deleteBasicBlock
+    :: BasicBlockRef -> IO ()
+foreign import ccall unsafe "LLVMRemoveBasicBlockFromParent" removeBasicBlockFromParent
+    :: BasicBlockRef -> IO ()
+foreign import ccall unsafe "LLVMMoveBasicBlockBefore" moveBasicBlockBefore
+    :: BasicBlockRef -> BasicBlockRef -> IO ()
+foreign import ccall unsafe "LLVMMoveBasicBlockAfter" moveBasicBlockAfter
+    :: BasicBlockRef -> BasicBlockRef -> IO ()
+foreign import ccall unsafe "LLVMGetFirstInstruction" getFirstInstruction
+    :: BasicBlockRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetLastInstruction" getLastInstruction
+    :: BasicBlockRef -> IO ValueRef
+
+-- ** Instructions
+foreign import ccall unsafe "LLVMGetInstructionParent" getInstructionParent
+    :: ValueRef -> IO BasicBlockRef
+foreign import ccall unsafe "LLVMGetNextInstruction" getNextInstruction
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMGetPreviousInstruction" getPreviousInstruction
+    :: ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMInstructionEraseFromParent" instructionEraseFromParent
+    :: ValueRef -> IO ()
+foreign import ccall unsafe "LLVMGetInstructionOpcode" getInstructionOpcode
+    :: ValueRef -> IO Int
+foreign import ccall unsafe "LLVMGetICmpPredicate" getICmpPredicate
+    :: ValueRef -> IO Int
+
+-- ** Call sites
+foreign import ccall unsafe "LLVMSetInstructionCallConv" setInstructionCallConv
+    :: ValueRef -> CUInt -> IO ()
+foreign import ccall unsafe "LLVMGetInstructionCallConv" getInstructionCallConv
+    :: ValueRef -> IO CUInt
+foreign import ccall unsafe "LLVMAddInstrAttribute" addInstrAttribute
+    :: ValueRef -> CUInt -> CAttribute -> IO ()
+foreign import ccall unsafe "LLVMRemoveInstrAttribute" removeInstrAttribute
+    :: ValueRef -> CUInt -> CAttribute -> IO ()
+foreign import ccall unsafe "LLVMSetInstrParamAlignment" setInstrParamAlignment
+    :: ValueRef -> CUInt -> CUInt -> IO ()
+
+-- ** Call instructions
+foreign import ccall unsafe "LLVMIsTailCall" isTailCall
+    :: ValueRef -> IO CInt
+foreign import ccall unsafe "LLVMSetTailCall" setTailCall
+    :: ValueRef -> CInt -> IO ()
+
+-- ** Switch Instructions
+foreign import ccall unsafe "LLVMGetSwitchDefaultDest" getSwitchDefaultDest
+    :: ValueRef -> IO BasicBlockRef
+
+-- ** Phi Nodes
+foreign import ccall unsafe "LLVMAddIncoming" addIncoming
+    :: ValueRef -> Ptr ValueRef -> Ptr ValueRef -> CUInt -> IO ()
+foreign import ccall unsafe "LLVMCountIncoming" countIncoming
+    :: ValueRef -> IO CUInt
+foreign import ccall unsafe "LLVMGetIncomingValue" getIncomingValue
+    :: ValueRef -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMGetIncomingBlock" getIncomingBlock
+    :: ValueRef -> CUInt -> IO BasicBlockRef
+
+-- ** Builders
+foreign import ccall unsafe "LLVMCreateBuilderInContext" createBuilderInContext
+    :: ContextRef -> IO BuilderRef
+foreign import ccall unsafe "LLVMCreateBuilder" createBuilder
+    :: IO BuilderRef
+foreign import ccall unsafe "LLVMPositionBuilder" positionBuilder
+    :: BuilderRef -> BasicBlockRef -> ValueRef -> IO ()
+foreign import ccall unsafe "LLVMPositionBuilderBefore" positionBefore
+    :: BuilderRef -> ValueRef -> IO ()
+foreign import ccall unsafe "LLVMPositionBuilderAtEnd" positionAtEnd
+    :: BuilderRef -> BasicBlockRef -> IO ()
+foreign import ccall unsafe "LLVMGetInsertBlock" getInsertBlock
+    :: BuilderRef -> IO BasicBlockRef
+foreign import ccall unsafe "LLVMClearInsertionPosition" clearInsertionPosition
+    :: BuilderRef -> IO ()
+foreign import ccall unsafe "LLVMInsertIntoBuilder" insertIntoBuilder
+    :: BuilderRef -> ValueRef -> IO ()
+foreign import ccall unsafe "LLVMInsertIntoBuilderWithName" insertIntoBuilderWithName
+    :: BuilderRef -> ValueRef -> CString -> IO ()
+foreign import ccall unsafe "&LLVMDisposeBuilder" ptrDisposeBuilder
+    :: FunPtr (BuilderRef -> IO ())
+
+-- ** Metadata
+foreign import ccall unsafe "LLVMGetCurrentDebugLocation" getCurrentDebugLocation
+    :: BuilderRef -> IO ValueRef
+foreign import ccall unsafe "LLVMSetCurrentDebugLocation" setCurrentDebugLocation
+    :: BuilderRef -> ValueRef -> IO ()
+foreign import ccall unsafe "LLVMSetInstDebugLocation" setInstDebugLocation
+    :: BuilderRef -> ValueRef -> IO ()
+
+-- ** Terminators
+foreign import ccall unsafe "LLVMBuildRetVoid" buildRetVoid
+    :: BuilderRef -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildRet" buildRet
+    :: BuilderRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildAggregateRet" buildAggregateRet
+    :: BuilderRef -> (Ptr ValueRef) -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildBr" buildBr
+    :: BuilderRef -> BasicBlockRef -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildCondBr" buildCondBr
+    :: BuilderRef -> ValueRef -> BasicBlockRef -> BasicBlockRef -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildSwitch" buildSwitch
+    :: BuilderRef -> ValueRef -> BasicBlockRef -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildIndirectBr" buildIndirectBr
+    :: BuilderRef -> ValueRef -> CUInt -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildInvoke" buildInvoke
+    :: BuilderRef -> ValueRef -> Ptr ValueRef -> CUInt
+    -> BasicBlockRef -> BasicBlockRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildLandingPad" buildLandingPad
+    :: BuilderRef -> TypeRef -> ValueRef -> CUInt -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildResume" buildResume
+    :: BuilderRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildUnreachable" buildUnreachable
+    :: BuilderRef -> IO ValueRef
+
+-- ** Switch instructions
+foreign import ccall unsafe "LLVMAddCase" addCase
+    :: ValueRef -> ValueRef -> BasicBlockRef -> IO ()
+
+-- ** IndirectBr instructions
+foreign import ccall unsafe "LLVMAddDestination" addDestination
+    :: ValueRef -> BasicBlockRef -> IO ()
+
+-- ** LandingPad instructions
+foreign import ccall unsafe "LLVMAddClause" addClause
+    :: ValueRef -> ValueRef -> IO ()
+
+-- ** Resume instructions
+foreign import ccall unsafe "LLVMSetCleanup" setCleanup
+    :: ValueRef -> CInt -> IO ()
+
+-- ** Arithmetic
+foreign import ccall unsafe "LLVMBuildAdd" buildAdd
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildNSWAdd" buildNSWAdd
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildNUWAdd" buildNUWAdd
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFAdd" buildFAdd
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildSub" buildSub
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildNSWSub" buildNSWSub
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildNUWSub" buildNUWSub
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFSub" buildFSub
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildMul" buildMul
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildNSWMul" buildNSWMul
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildNUWMul" buildNUWMul
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFMul" buildFMul
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildUDiv" buildUDiv
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildSDiv" buildSDiv
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildExactSDiv" buildExactSDiv
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFDiv" buildFDiv
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildURem" buildURem
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildSRem" buildSRem
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFRem" buildFRem
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildShl" buildShl
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildLShr" buildLShr
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildAShr" buildAShr
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildAnd" buildAnd
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildOr" buildOr
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildXor" buildXor
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildBinOp" buildBinOp
+    :: BuilderRef -> CUInt{-Opcode-} -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildNeg" buildNeg
+    :: BuilderRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildNSWNeg" buildNSWNeg
+    :: BuilderRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildNUWNeg" buildNUWNeg
+    :: BuilderRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFNeg" buildFNeg
+    :: BuilderRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildNot" buildNot
+    :: BuilderRef -> ValueRef -> CString -> IO ValueRef
+
+-- ** Memory
+foreign import ccall unsafe "LLVMBuildMalloc" buildMalloc
+    :: BuilderRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildArrayMalloc" buildArrayMalloc
+    :: BuilderRef -> TypeRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildAlloca" buildAlloca
+    :: BuilderRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildArrayAlloca" buildArrayAlloca
+    :: BuilderRef -> TypeRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFree" buildFree
+    :: BuilderRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildLoad" buildLoad
+    :: BuilderRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildStore" buildStore
+    :: BuilderRef -> ValueRef -> ValueRef -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildGEP" buildGEP
+    :: BuilderRef -> ValueRef -> Ptr ValueRef -> CUInt -> CString
+    -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildInBoundsGEP" buildInBoundsGEP
+    :: BuilderRef -> ValueRef -> (Ptr ValueRef) -> CUInt -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildStructGEP" buildStructGEP
+    :: BuilderRef -> ValueRef -> CUInt -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildGlobalString" buildGlobalString
+    :: BuilderRef -> CString -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildGlobalStringPtr" buildGlobalStringPtr
+    :: BuilderRef -> CString -> CString -> IO ValueRef
+
+-- Casts
+foreign import ccall unsafe "LLVMBuildTrunc" buildTrunc
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildZExt" buildZExt
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildSExt" buildSExt
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFPToUI" buildFPToUI
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFPToSI" buildFPToSI
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildUIToFP" buildUIToFP
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildSIToFP" buildSIToFP
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFPTrunc" buildFPTrunc
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFPExt" buildFPExt
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildPtrToInt" buildPtrToInt
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildIntToPtr" buildIntToPtr
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildBitCast" buildBitCast
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildZExtOrBitCast" buildZExtOrBitCast
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildSExtOrBitCast" buildSExtOrBitCast
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildTruncOrBitCast" buildTruncOrBitCast
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildCast" buildCast
+    :: BuilderRef -> CUInt{-Opcode-} -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildPointerCast" buildPointerCast
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildIntCast" buildIntCast
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFPCast" buildFPCast
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+
+-- Comparisons
+foreign import ccall unsafe "LLVMBuildICmp" buildICmp
+    :: BuilderRef -> CInt -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildFCmp" buildFCmp
+    :: BuilderRef -> CInt -> ValueRef -> ValueRef -> CString -> IO ValueRef
+
+-- Miscellaneous instructions
+foreign import ccall unsafe "LLVMBuildPhi" buildPhi
+    :: BuilderRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildCall" buildCall
+    :: BuilderRef -> ValueRef -> Ptr ValueRef -> CUInt -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildSelect" buildSelect
+    :: BuilderRef -> ValueRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildVAArg" buildVAArg
+    :: BuilderRef -> ValueRef -> TypeRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildExtractElement" buildExtractElement
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildInsertElement" buildInsertElement
+    :: BuilderRef -> ValueRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildShuffleVector" buildShuffleVector
+    :: BuilderRef -> ValueRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildExtractValue" buildExtractValue
+    :: BuilderRef -> ValueRef -> CUInt -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildInsertValue" buildInsertValue
+    :: BuilderRef -> ValueRef -> ValueRef -> CUInt -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildIsNull" buildIsNull
+    :: BuilderRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildIsNotNull" buildIsNotNull
+    :: BuilderRef -> ValueRef -> CString -> IO ValueRef
+foreign import ccall unsafe "LLVMBuildPtrDiff" buildPtrDiff
+    :: BuilderRef -> ValueRef -> ValueRef -> CString -> IO ValueRef
+
+
+-- ** Module Providers
+foreign import ccall unsafe "LLVMCreateModuleProviderForExistingModule"
+    createModuleProviderForExistingModule
+    :: ModuleRef -> IO ModuleProviderRef
+foreign import ccall unsafe "&LLVMDisposeModuleProvider" ptrDisposeModuleProvider
+    :: FunPtr (ModuleProviderRef -> IO ())
+
+
+-- ** Memory Buffers
+foreign import ccall unsafe "LLVMCreateMemoryBufferWithContentsOfFile" createMemoryBufferWithContentsOfFile
+    :: CString -> Ptr MemoryBufferRef -> Ptr CString -> IO CInt
+foreign import ccall unsafe "LLVMCreateMemoryBufferWithSTDIN" createMemoryBufferWithSTDIN
+    :: Ptr MemoryBufferRef -> Ptr CString -> IO CInt
+foreign import ccall unsafe "LLVMDisposeMemoryBuffer" disposeMemoryBuffer
+    :: MemoryBufferRef -> IO ()
+
+-- ** Pass Registry
+foreign import ccall unsafe "LLVMGetGlobalPassRegistry" getGlobalPassRegistry
+    :: IO PassRegistryRef
+
+-- ** Pass Managers
+foreign import ccall unsafe "LLVMCreatePassManager" createPassManager
+    :: IO PassManagerRef
+foreign import ccall unsafe "LLVMCreateFunctionPassManagerForModule" createFunctionPassManagerForModule
+    :: ModuleRef -> IO PassManagerRef
+foreign import ccall unsafe "LLVMCreateFunctionPassManager" createFunctionPassManager
+    :: ModuleProviderRef -> IO PassManagerRef
+foreign import ccall unsafe "LLVMRunPassManager" runPassManager
+    :: PassManagerRef -> ModuleRef -> IO CInt
+foreign import ccall unsafe "LLVMInitializeFunctionPassManager" initializeFunctionPassManager
+    :: PassManagerRef -> IO CInt
+foreign import ccall unsafe "LLVMRunFunctionPassManager" runFunctionPassManager
+    :: PassManagerRef -> ValueRef -> IO CInt
+foreign import ccall unsafe "LLVMFinalizeFunctionPassManager" finalizeFunctionPassManager
+    :: PassManagerRef -> IO CInt
+foreign import ccall unsafe "LLVMDisposePassManager" disposePassManager
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "&LLVMDisposePassManager" ptrDisposePassManager
+    :: FunPtr (PassManagerRef -> IO ())
+
+-- ** Functions from extras.cpp
+foreign import ccall unsafe "LLVMValueGetNumUses" getNumUses
+    :: ValueRef -> IO CInt
+foreign import ccall unsafe "LLVMInstGetOpcode" instGetOpcode
+    :: ValueRef -> IO CInt
+foreign import ccall unsafe "LLVMCmpInstGetPredicate" cmpInstGetPredicate
+    :: ValueRef -> IO CInt
diff --git a/src/LLVM/FFI/ExecutionEngine.hsc b/src/LLVM/FFI/ExecutionEngine.hsc
new file mode 100644
--- /dev/null
+++ b/src/LLVM/FFI/ExecutionEngine.hsc
@@ -0,0 +1,165 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE EmptyDataDecls #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+
+module LLVM.FFI.ExecutionEngine
+    (
+    -- * Linking
+      linkInInterpreter
+    , linkInJIT
+
+    -- * Generic values
+    , GenericValue
+    , GenericValueRef
+    , createGenericValueOfInt
+    , createGenericValueOfPointer
+    , createGenericValueOfFloat
+    , genericValueIntWidth
+    , genericValueToInt
+    , genericValueToPointer
+    , genericValueToFloat
+    , ptrDisposeGenericValue
+
+    -- * Execution engines
+    , ExecutionEngine
+    , ExecutionEngineRef
+    , createExecutionEngineForModule
+    , createInterpreterForModule
+    , createJITCompilerForModule
+    , createExecutionEngine
+    , createInterpreter
+    , createJITCompiler
+    , ptrDisposeExecutionEngine
+    , disposeExecutionEngine
+    , runStaticConstructors
+    , runStaticDestructors
+    , runFunctionAsMain
+    , freeMachineCodeForFunction
+    , addModule
+    , addModuleProvider
+    , removeModule
+    , removeModuleProvider
+    , findFunction
+    , recompileAndRelinkFunction
+    , runFunction
+    , getExecutionEngineTargetData
+    , addGlobalMapping
+    , addFunctionMapping
+    , getPointerToGlobal
+
+    ) where
+
+import LLVM.FFI.Core (ModuleRef, ModuleProviderRef, TypeRef, ValueRef)
+import LLVM.FFI.Target(TargetDataRef)
+
+import qualified Foreign.C.Types as C
+import Foreign.C.String (CString)
+import Foreign.Ptr (Ptr, FunPtr)
+
+import Data.Typeable (Typeable)
+
+
+type CDouble  = C.CDouble
+type CInt     = C.CInt
+type CUInt    = C.CUInt
+type CULLong  = C.CULLong
+
+
+data ExecutionEngine
+    deriving (Typeable)
+type ExecutionEngineRef = Ptr ExecutionEngine
+
+data GenericValue
+    deriving (Typeable)
+type GenericValueRef = Ptr GenericValue
+
+-- ** Linking
+foreign import ccall unsafe "LLVMLinkInInterpreter" linkInInterpreter
+    :: IO ()
+foreign import ccall unsafe "LLVMLinkInJIT" linkInJIT
+    :: IO ()
+
+-- ** Generic values
+foreign import ccall unsafe "LLVMCreateGenericValueOfInt"
+    createGenericValueOfInt :: TypeRef -> CULLong -> CInt
+                            -> IO GenericValueRef
+foreign import ccall unsafe "LLVMCreateGenericValueOfPointer"
+    createGenericValueOfPointer :: Ptr a -> IO GenericValueRef
+foreign import ccall unsafe "LLVMCreateGenericValueOfFloat"
+    createGenericValueOfFloat :: TypeRef -> CDouble -> IO GenericValueRef
+foreign import ccall unsafe "LLVMGenericValueIntWidth" genericValueIntWidth
+    :: GenericValueRef -> IO CUInt
+foreign import ccall unsafe "LLVMGenericValueToInt" genericValueToInt
+    :: GenericValueRef -> CInt -> IO CULLong
+foreign import ccall unsafe "LLVMGenericValueToPointer" genericValueToPointer
+    :: GenericValueRef -> IO (Ptr a)
+foreign import ccall unsafe "LLVMGenericValueToFloat" genericValueToFloat
+    :: TypeRef -> GenericValueRef -> IO CDouble
+foreign import ccall unsafe "&LLVMDisposeGenericValue" ptrDisposeGenericValue
+    :: FunPtr (GenericValueRef -> IO ())
+
+-- ** Execution engines
+foreign import ccall unsafe "LLVMCreateExecutionEngineForModule" createExecutionEngineForModule
+    :: (Ptr ExecutionEngineRef) -> ModuleRef -> (Ptr CString) -> IO Bool
+foreign import ccall unsafe "LLVMCreateInterpreterForModule" createInterpreterForModule
+    :: (Ptr ExecutionEngineRef) -> ModuleRef -> (Ptr CString) -> IO Bool
+foreign import ccall unsafe "LLVMCreateJITCompilerForModule" createJITCompilerForModule
+    :: (Ptr ExecutionEngineRef) -> ModuleRef -> CUInt -> (Ptr CString) -> IO Bool
+foreign import ccall unsafe "LLVMCreateExecutionEngine" createExecutionEngine
+    :: Ptr ExecutionEngineRef -> ModuleProviderRef -> Ptr CString
+    -> IO CInt
+foreign import ccall unsafe "LLVMCreateInterpreter" createInterpreter
+    :: Ptr ExecutionEngineRef -> ModuleProviderRef -> Ptr CString -> IO CInt
+foreign import ccall unsafe "LLVMCreateJITCompiler" createJITCompiler
+    :: Ptr ExecutionEngineRef -> ModuleProviderRef -> CUInt -> Ptr CString -> IO CInt
+foreign import ccall unsafe "LLVMDisposeExecutionEngine" disposeExecutionEngine
+    :: ExecutionEngineRef -> IO ()
+foreign import ccall unsafe "&LLVMDisposeExecutionEngine" ptrDisposeExecutionEngine
+    :: FunPtr (ExecutionEngineRef -> IO ())
+foreign import ccall unsafe "LLVMRunStaticConstructors" runStaticConstructors
+    :: ExecutionEngineRef -> IO ()
+foreign import ccall unsafe "LLVMRunStaticDestructors" runStaticDestructors
+    :: ExecutionEngineRef -> IO ()
+{-
+safe call is important, since the running LLVM code may call back into Haskell code
+
+See
+http://www.cse.unsw.edu.au/~chak/haskell/ffi/ffi/ffise3.html#x6-130003.3 says:
+
+"Optionally, an import declaration can specify,
+after the calling  convention,
+the safety level that should be used when invoking an external entity.
+..."
+-}
+foreign import ccall safe "LLVMRunFunctionAsMain" runFunctionAsMain
+    :: ExecutionEngineRef -> ValueRef -> CUInt
+    -> Ptr CString              -- ^ argv
+    -> Ptr CString              -- ^ envp
+    -> IO CInt
+foreign import ccall safe "LLVMRunFunction" runFunction
+    :: ExecutionEngineRef -> ValueRef -> CUInt
+    -> Ptr GenericValueRef -> IO GenericValueRef
+foreign import ccall unsafe "LLVMFreeMachineCodeForFunction"
+    freeMachineCodeForFunction :: ExecutionEngineRef -> ValueRef -> IO ()
+foreign import ccall unsafe "LLVMAddModule" addModule
+    :: ExecutionEngineRef -> ModuleRef -> IO ()
+foreign import ccall unsafe "LLVMAddModuleProvider" addModuleProvider
+    :: ExecutionEngineRef -> ModuleProviderRef -> IO ()
+foreign import ccall unsafe "LLVMRemoveModule" removeModule
+    :: ExecutionEngineRef -> ModuleRef -> (Ptr ModuleRef) -> (Ptr CString) -> IO Bool
+foreign import ccall unsafe "LLVMRemoveModuleProvider" removeModuleProvider
+    :: ExecutionEngineRef -> ModuleProviderRef -> Ptr ModuleRef -> Ptr CString
+    -> IO CInt
+foreign import ccall unsafe "LLVMFindFunction" findFunction
+    :: ExecutionEngineRef -> CString -> Ptr ValueRef -> IO CInt
+foreign import ccall unsafe "LLVMRecompileAndRelinkFunction" recompileAndRelinkFunction
+    :: ExecutionEngineRef -> ValueRef -> IO (FunPtr a)
+foreign import ccall unsafe "LLVMGetExecutionEngineTargetData" getExecutionEngineTargetData
+    :: ExecutionEngineRef -> IO TargetDataRef
+foreign import ccall unsafe "LLVMAddGlobalMapping" addGlobalMapping
+    :: ExecutionEngineRef -> ValueRef -> Ptr a -> IO ()
+foreign import ccall unsafe "LLVMAddGlobalMapping" addFunctionMapping
+    :: ExecutionEngineRef -> ValueRef -> FunPtr a -> IO ()
+foreign import ccall unsafe "LLVMGetPointerToGlobal" getPointerToGlobal
+    :: ExecutionEngineRef -> ValueRef -> IO (FunPtr a)
diff --git a/src/LLVM/FFI/Support.hsc b/src/LLVM/FFI/Support.hsc
new file mode 100644
--- /dev/null
+++ b/src/LLVM/FFI/Support.hsc
@@ -0,0 +1,23 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+
+module LLVM.FFI.Support
+    (
+      createStandardModulePasses
+    , createStandardFunctionPasses
+    ) where
+
+import qualified Foreign.C.Types as C
+
+import LLVM.FFI.Core (PassManagerRef)
+
+
+type CUInt = C.CUInt
+type CInt = C.CInt
+
+
+foreign import ccall unsafe "LLVMCreateStandardFunctionPasses" createStandardFunctionPasses
+    :: PassManagerRef -> CUInt -> IO ()
+
+foreign import ccall unsafe "LLVMCreateStandardModulePasses" createStandardModulePasses
+    :: PassManagerRef -> CUInt -> CInt -> CInt -> CInt -> CInt -> CInt -> CInt -> IO ()
diff --git a/src/LLVM/FFI/Target.hsc b/src/LLVM/FFI/Target.hsc
new file mode 100644
--- /dev/null
+++ b/src/LLVM/FFI/Target.hsc
@@ -0,0 +1,66 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE EmptyDataDecls #-}
+{-# LANGUAGE DeriveDataTypeable #-}
+
+module LLVM.FFI.Target where
+
+import LLVM.FFI.Core (ValueRef, TypeRef, PassManagerRef)
+
+import qualified Foreign.C.Types as C
+import Foreign.C.String (CString)
+import Foreign.Ptr (Ptr)
+
+import Data.Typeable (Typeable)
+
+
+type CUInt = C.CUInt
+type CInt = C.CInt
+type CULLong = C.CULLong
+
+
+-- enum { LLVMBigEndian, LLVMLittleEndian };
+type ByteOrdering = CInt
+
+data TargetData
+    deriving (Typeable)
+type TargetDataRef = Ptr TargetData
+
+data TargetLibraryInfo
+    deriving (Typeable)
+type TargetLibraryInfoRef = Ptr TargetLibraryInfo
+
+foreign import ccall unsafe "LLVMCreateTargetData" createTargetData
+    :: CString -> IO TargetDataRef
+foreign import ccall unsafe "LLVMAddTargetData" addTargetData
+    :: TargetDataRef -> PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddTargetLibraryInfo" addTargetLibraryInfo
+    :: TargetLibraryInfoRef -> PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMCopyStringRepOfTargetData" copyStringRepOfTargetData
+    :: TargetDataRef -> IO CString
+foreign import ccall unsafe "LLVMByteOrder" byteOrder
+    :: TargetDataRef -> IO ByteOrdering
+foreign import ccall unsafe "LLVMPointerSize" pointerSize
+    :: TargetDataRef -> IO CUInt
+foreign import ccall unsafe "LLVMIntPtrType" intPtrType
+    :: TargetDataRef -> IO TypeRef
+foreign import ccall unsafe "LLVMSizeOfTypeInBits" sizeOfTypeInBits
+    :: TargetDataRef -> TypeRef -> IO CULLong
+foreign import ccall unsafe "LLVMStoreSizeOfType" storeSizeOfType
+    :: TargetDataRef -> TypeRef -> IO CULLong
+foreign import ccall unsafe "LLVMABISizeOfType" aBISizeOfType
+    :: TargetDataRef -> TypeRef -> IO CULLong
+foreign import ccall unsafe "LLVMABIAlignmentOfType" aBIAlignmentOfType
+    :: TargetDataRef -> TypeRef -> IO CULLong
+foreign import ccall unsafe "LLVMCallFrameAlignmentOfType" callFrameAlignmentOfType
+    :: TargetDataRef -> TypeRef -> IO CULLong
+foreign import ccall unsafe "LLVMPreferredAlignmentOfType" preferredAlignmentOfType
+    :: TargetDataRef -> TypeRef -> IO CULLong
+foreign import ccall unsafe "LLVMPreferredAlignmentOfGlobal" preferredAlignmentOfGlobal
+    :: TargetDataRef -> ValueRef -> IO CUInt
+foreign import ccall unsafe "LLVMElementAtOffset" elementAtOffset
+    :: TargetDataRef -> TypeRef -> CULLong -> IO CUInt
+foreign import ccall unsafe "LLVMOffsetOfElement" offsetOfElement
+    :: TargetDataRef -> TypeRef -> CUInt -> IO CULLong
+foreign import ccall unsafe "LLVMDisposeTargetData" disposeTargetData
+    :: TargetDataRef -> IO ()
diff --git a/src/LLVM/FFI/Transforms/IPO.hsc b/src/LLVM/FFI/Transforms/IPO.hsc
new file mode 100644
--- /dev/null
+++ b/src/LLVM/FFI/Transforms/IPO.hsc
@@ -0,0 +1,37 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE EmptyDataDecls #-}
+
+module LLVM.FFI.Transforms.IPO where
+
+import LLVM.FFI.Core (PassManagerRef)
+
+
+foreign import ccall unsafe "LLVMAddArgumentPromotionPass" addArgumentPromotionPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddConstantMergePass" addConstantMergePass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddDeadArgEliminationPass" addDeadArgEliminationPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddFunctionAttrsPass" addFunctionAttrsPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddFunctionInliningPass" addFunctionInliningPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddAlwaysInlinerPass" addAlwaysInlinerPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddGlobalDCEPass" addGlobalDCEPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddGlobalOptimizerPass" addGlobalOptimizerPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddIPConstantPropagationPass" addIPConstantPropagationPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddPruneEHPass" addPruneEHPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddIPSCCPPass" addIPSCCPPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddInternalizePass" addInternalizePass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddStripDeadPrototypesPass" addStripDeadPrototypesPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddStripSymbolsPass" addStripSymbolsPass
+    :: PassManagerRef -> IO ()
diff --git a/src/LLVM/FFI/Transforms/Scalar.hsc b/src/LLVM/FFI/Transforms/Scalar.hsc
new file mode 100644
--- /dev/null
+++ b/src/LLVM/FFI/Transforms/Scalar.hsc
@@ -0,0 +1,70 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE EmptyDataDecls #-}
+
+module LLVM.FFI.Transforms.Scalar where
+
+import LLVM.FFI.Core (PassManagerRef)
+
+
+foreign import ccall unsafe "LLVMAddAggressiveDCEPass" addAggressiveDCEPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddCFGSimplificationPass" addCFGSimplificationPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddDeadStoreEliminationPass" addDeadStoreEliminationPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddGVNPass" addGVNPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddIndVarSimplifyPass" addIndVarSimplifyPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddInstructionCombiningPass" addInstructionCombiningPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddJumpThreadingPass" addJumpThreadingPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddLICMPass" addLICMPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddLoopDeletionPass" addLoopDeletionPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddLoopIdiomPass" addLoopIdiomPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddLoopRotatePass" addLoopRotatePass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddLoopUnrollPass" addLoopUnrollPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddLoopUnswitchPass" addLoopUnswitchPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddMemCpyOptPass" addMemCpyOptPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddPromoteMemoryToRegisterPass" addPromoteMemoryToRegisterPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddReassociatePass" addReassociatePass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddSCCPPass" addSCCPPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddScalarReplAggregatesPass" addScalarReplAggregatesPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddScalarReplAggregatesPassSSA" addScalarReplAggregatesPassSSA
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddScalarReplAggregatesPassWithThreshold"
+        addScalarReplAggregatesPassWithThreshold
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddSimplifyLibCallsPass" addSimplifyLibCallsPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddTailCallEliminationPass" addTailCallEliminationPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddConstantPropagationPass" addConstantPropagationPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddDemoteMemoryToRegisterPass" addDemoteMemoryToRegisterPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddVerifierPass" addVerifierPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddCorrelatedValuePropagationPass" addCorrelatedValuePropagationPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddEarlyCSEPass" addEarlyCSEPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddLowerExpectIntrinsicPass" addLowerExpectIntrinsicPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddTypeBasedAliasAnalysisPass" addTypeBasedAliasAnalysisPass
+    :: PassManagerRef -> IO ()
+foreign import ccall unsafe "LLVMAddBasicAliasAnalysisPass" addBasicAliasAnalysisPass
+    :: PassManagerRef -> IO ()
diff --git a/src/LLVM/Target/ARM.hs b/src/LLVM/Target/ARM.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/ARM.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.ARM(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializeARMTargetInfo
+    initializeARMTarget
+
+foreign import ccall unsafe "LLVMInitializeARMTargetInfo" initializeARMTargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializeARMTarget" initializeARMTarget :: IO ()
diff --git a/src/LLVM/Target/Alpha.hs b/src/LLVM/Target/Alpha.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/Alpha.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.Alpha(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializeAlphaTargetInfo
+    initializeAlphaTarget
+
+foreign import ccall unsafe "LLVMInitializeAlphaTargetInfo" initializeAlphaTargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializeAlphaTarget" initializeAlphaTarget :: IO ()
diff --git a/src/LLVM/Target/Blackfin.hs b/src/LLVM/Target/Blackfin.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/Blackfin.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.Blackfin(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializeBlackfinTargetInfo
+    initializeBlackfinTarget
+
+foreign import ccall unsafe "LLVMInitializeBlackfinTargetInfo" initializeBlackfinTargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializeBlackfinTarget" initializeBlackfinTarget :: IO ()
diff --git a/src/LLVM/Target/CBackend.hs b/src/LLVM/Target/CBackend.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/CBackend.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.CBackend(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializeCBackendTargetInfo
+    initializeCBackendTarget
+
+foreign import ccall unsafe "LLVMInitializeCBackendTargetInfo" initializeCBackendTargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializeCBackendTarget" initializeCBackendTarget :: IO ()
diff --git a/src/LLVM/Target/CellSPU.hs b/src/LLVM/Target/CellSPU.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/CellSPU.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.CellSPU(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializeCellSPUTargetInfo
+    initializeCellSPUTarget
+
+foreign import ccall unsafe "LLVMInitializeCellSPUTargetInfo" initializeCellSPUTargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializeCellSPUTarget" initializeCellSPUTarget :: IO ()
diff --git a/src/LLVM/Target/CppBackend.hs b/src/LLVM/Target/CppBackend.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/CppBackend.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.CppBackend(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializeCppBackendTargetInfo
+    initializeCppBackendTarget
+
+foreign import ccall unsafe "LLVMInitializeCppBackendTargetInfo" initializeCppBackendTargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializeCppBackendTarget" initializeCppBackendTarget :: IO ()
diff --git a/src/LLVM/Target/MSP430.hs b/src/LLVM/Target/MSP430.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/MSP430.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.MSP430(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializeMSP430TargetInfo
+    initializeMSP430Target
+
+foreign import ccall unsafe "LLVMInitializeMSP430TargetInfo" initializeMSP430TargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializeMSP430Target" initializeMSP430Target :: IO ()
diff --git a/src/LLVM/Target/Mips.hs b/src/LLVM/Target/Mips.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/Mips.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.Mips(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializeMipsTargetInfo
+    initializeMipsTarget
+
+foreign import ccall unsafe "LLVMInitializeMipsTargetInfo" initializeMipsTargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializeMipsTarget" initializeMipsTarget :: IO ()
diff --git a/src/LLVM/Target/Native.hs b/src/LLVM/Target/Native.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/Native.hs
@@ -0,0 +1,25 @@
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.Native(initializeNativeTarget) where
+
+import qualified Foreign.C.Types as C
+
+import Control.Concurrent.MVar (MVar, newMVar, takeMVar, putMVar)
+import Control.Monad (when)
+
+import System.IO.Unsafe (unsafePerformIO)
+
+
+foreign import ccall unsafe "LLVMInitNativeTarget"
+        llvmInitializeNativeTarget :: IO C.CUInt
+
+-- | Initialize jitter to the native target.
+-- The operation is idempotent.
+initializeNativeTarget :: IO ()
+initializeNativeTarget = do
+    done <- takeMVar refDone
+    when (not done) (llvmInitializeNativeTarget >> return ()) -- initializeTarget
+    putMVar refDone True
+
+-- UNSAFE: global variable to keep track of initialization state.
+refDone :: MVar Bool
+refDone = unsafePerformIO $ newMVar False
diff --git a/src/LLVM/Target/PowerPC.hs b/src/LLVM/Target/PowerPC.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/PowerPC.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.PowerPC(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializePowerPCTargetInfo
+    initializePowerPCTarget
+
+foreign import ccall unsafe "LLVMInitializePowerPCTargetInfo" initializePowerPCTargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializePowerPCTarget" initializePowerPCTarget :: IO ()
diff --git a/src/LLVM/Target/Sparc.hs b/src/LLVM/Target/Sparc.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/Sparc.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.Sparc(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializeSparcTargetInfo
+    initializeSparcTarget
+
+foreign import ccall unsafe "LLVMInitializeSparcTargetInfo" initializeSparcTargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializeSparcTarget" initializeSparcTarget :: IO ()
diff --git a/src/LLVM/Target/SystemZ.hs b/src/LLVM/Target/SystemZ.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/SystemZ.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.SystemZ(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializeSystemZTargetInfo
+    initializeSystemZTarget
+
+foreign import ccall unsafe "LLVMInitializeSystemZTargetInfo" initializeSystemZTargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializeSystemZTarget" initializeSystemZTarget :: IO ()
diff --git a/src/LLVM/Target/X86.hs b/src/LLVM/Target/X86.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/X86.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.X86(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializeX86TargetInfo
+    initializeX86Target
+
+foreign import ccall unsafe "LLVMInitializeX86TargetInfo" initializeX86TargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializeX86Target" initializeX86Target :: IO ()
diff --git a/src/LLVM/Target/XCore.hs b/src/LLVM/Target/XCore.hs
new file mode 100644
--- /dev/null
+++ b/src/LLVM/Target/XCore.hs
@@ -0,0 +1,11 @@
+{-# LANGUAGE Safe #-}
+{-# LANGUAGE ForeignFunctionInterface #-}
+module LLVM.Target.XCore(initializeTarget) where
+
+initializeTarget :: IO ()
+initializeTarget = do
+    initializeXCoreTargetInfo
+    initializeXCoreTarget
+
+foreign import ccall unsafe "LLVMInitializeXCoreTargetInfo" initializeXCoreTargetInfo :: IO ()
+foreign import ccall unsafe "LLVMInitializeXCoreTarget" initializeXCoreTarget :: IO ()
diff --git a/tool/DiffFFI.hs b/tool/DiffFFI.hs
new file mode 100644
--- /dev/null
+++ b/tool/DiffFFI.hs
@@ -0,0 +1,46 @@
+module Main (main) where
+
+import FunctionMangulation (pattern, rewriteFunction)
+
+import Text.Regex.Posix ((=~))
+
+import qualified Data.Map as Map
+import Data.Map (Map)
+import Data.Maybe (mapMaybe)
+
+import Control.Monad (forM_)
+
+import System.Environment (getArgs)
+import System.Exit (exitFailure)
+import System.IO (hPutStrLn, stderr)
+
+
+cFunctions :: String -> Map String String
+cFunctions s =
+   let f (_:ret:name:params:_) =
+            Just ("LLVM" ++ name, rewriteFunction ret name params)
+       f _ = Nothing
+   in  Map.fromList $ mapMaybe f (s =~ pattern)
+
+hsFunctions :: String -> Map String String
+hsFunctions s =
+   let pat = "\"([a-zA-Z0-9_]+)\"[ \t\n]+([a-zA-Z0-9_']+)"
+       f (_:cname:hsname:_) = Just (cname, hsname)
+       f _ = Nothing
+   in  Map.fromList $ mapMaybe f (s =~ pat)
+
+main :: IO ()
+main = do
+  args <- getArgs
+  case args of
+    [cFile, hsFile] -> do
+              c <- cFunctions `fmap` readFile cFile
+              hs <- hsFunctions `fmap` readFile hsFile
+              putStrLn "In C, not Haskell:"
+              forM_ (Map.toAscList $ Map.difference c hs) $ \(_, hsfunc) ->
+                    putStrLn hsfunc
+              putStrLn "In Haskell, not C:"
+              forM_ (Map.keys $ Map.difference hs c) $ putStrLn . ("  "++)
+    _ -> do
+         hPutStrLn stderr "Usage: DiffFFI cFile hsFile"
+         exitFailure
diff --git a/tool/FunctionMangler.hs b/tool/FunctionMangler.hs
new file mode 100644
--- /dev/null
+++ b/tool/FunctionMangler.hs
@@ -0,0 +1,9 @@
+module Main (main) where
+
+import FunctionMangulation (rewrite)
+
+import Data.List (intercalate)
+
+
+main :: IO ()
+main = interact (intercalate "\n\n" . concat . rewrite) >> putStr "\n"
diff --git a/tool/FunctionMangulation.hs b/tool/FunctionMangulation.hs
new file mode 100644
--- /dev/null
+++ b/tool/FunctionMangulation.hs
@@ -0,0 +1,69 @@
+module FunctionMangulation
+    (
+      pattern
+    , rewrite
+    , rewriteFunction
+    ) where
+
+import Text.Regex.Posix ((=~), (=~~))
+
+import Control.Monad (forM)
+import Data.Char (toLower)
+import Data.List.HT (maybePrefixOf)
+import Data.String.HT (trim)
+import Data.List (intercalate)
+
+
+pattern :: String
+pattern = "^([A-Za-z0-9_ ]+ ?\\*?)[ \t\n]*" ++
+          "LLVM([A-Za-z0-9_]+)\\(([a-zA-Z0-9_*, \t\n]+)\\);"
+
+renameType :: String -> String
+renameType t =
+   case maybePrefixOf "LLVM" t of
+      Just suffix -> rename suffix
+      Nothing -> rename t
+
+rename :: String -> String
+rename cname =
+   case cname of
+      "int" -> "CInt"
+      "unsigned" -> "CUInt"
+      "long long" -> "CLLong"
+      "unsigned long long" -> "CULLong"
+      "void" -> "()"
+      "const char *" -> "CString"
+      "char *" -> "CString"
+      _ ->
+         case reverse cname of
+            '*':ps -> "(Ptr " ++ rename (reverse ps) ++ ")"
+            _ -> trim cname
+
+split :: (a -> Bool) -> [a] -> [[a]]
+split p xs =
+   case break p xs of
+      (h,(_:t)) -> h : split p t
+      (s,_) -> [s]
+
+dropName :: String -> String
+dropName s =
+   case s =~ "^((const )?[A-Za-z0-9_]+( \\*+)?) ?[A-Za-z0-9]*$" of
+      ((_:typ:_):_) -> typ
+      _ -> "{- oops! -} " ++ s
+
+rewriteFunction :: String -> String -> String -> String
+rewriteFunction cret cname cparams =
+    let ret = "IO " ++ renameType (trim cret)
+        params = map renameParam . split (==',') $ cparams
+	params' = if params == ["()"] then [] else params
+        name = let (n:ame) = cname in toLower n : ame
+    in foreign ++ "\"LLVM" ++ cname ++ "\" " ++ name ++
+           "\n    :: " ++ intercalate " -> " (params' ++ [ret])
+  where renameParam = renameType . dropName . trim
+        foreign = "foreign import ccall unsafe "
+
+rewrite :: Monad m => String -> m [String]
+rewrite s = do
+    matches <- s =~~ pattern
+    forM matches $ \(_:cret:cname:cparams:_) ->
+         return (rewriteFunction cret cname cparams)
diff --git a/tool/IntrinsicMangler.hs b/tool/IntrinsicMangler.hs
new file mode 100644
--- /dev/null
+++ b/tool/IntrinsicMangler.hs
@@ -0,0 +1,23 @@
+module Main (main) where
+
+import qualified Data.ByteString.Char8 as C
+import Text.Regex.Posix ((=~~))
+import Control.Monad (forM_)
+import Data.Maybe (catMaybes)
+
+
+maybeName :: C.ByteString -> Maybe C.ByteString
+maybeName line = do
+  ((_:name:_):_) <- line =~~ "^[ \t]*([a-z0-9_]+),[ \t]*//[ \t]*llvm\\."
+  return name
+
+main :: IO ()
+main = do
+  input <- (catMaybes . map maybeName . C.lines) `fmap` C.getContents
+
+  putStrLn "-- automatically generated file - do not edit!"
+  putStrLn "module LLVM.Core.Intrinsics (Intrinsic(..)) where"
+  putStrLn "data Intrinsic ="
+  putStrLn "      NotIntrinsic"
+  forM_ input $ C.putStrLn . (C.append (C.pack "    | I_"))
+  putStrLn "    deriving (Eq, Ord, Enum, Show)"
diff --git a/tool/ltrace.config b/tool/ltrace.config
new file mode 100644
--- /dev/null
+++ b/tool/ltrace.config
@@ -0,0 +1,582 @@
+; Attention: ltrace does not accept a space between LLVMWriteBitcodeToFile and '('
+; but it also does not emit a parse error.
+
+typedef LLVMBool = enum (false = 0, true = 1)
+
+; it seems that typedef-types cannot be used for results
+; If we enable the following declarations instead of the other ones,
+; then they are silently ignored.
+
+; LLVMBool LLVMInitializeNativeTarget();
+
+; LLVMBool LLVMInitializeX86Target();
+; LLVMBool LLVMInitializeX86TargetInfo();
+
+int LLVMInitializeNativeTarget();
+
+int LLVMInitializeX86Target();
+int LLVMInitializeX86TargetInfo();
+
+
+typedef LLVMMemoryBufferRef = addr
+typedef LLVMModuleRef = addr
+typedef LLVMContextRef = addr
+
+
+; BitReader.h
+
+int LLVMParseBitcode(LLVMMemoryBufferRef, LLVMModuleRef*, string*);
+int LLVMParseBitcodeInContext(LLVMContextRef,LLVMMemoryBufferRef,LLVMModuleRef*, string*);
+int LLVMGetBitcodeModuleInContext(LLVMContextRef,LLVMMemoryBufferRef,LLVMModuleRef*,string*);
+int LLVMGetBitcodeModule(LLVMMemoryBufferRef, LLVMModuleRef*,string*);
+
+; BitWriter.h
+
+
+int LLVMWriteBitcodeToFile(LLVMModuleRef,string);
+int LLVMWriteBitcodeToFD(LLVMModuleRef,int,int,int);
+int LLVMWriteBitcodeToFileHandle(LLVMModuleRef,file);
+
+
+; Target.h
+
+typedef LLVMPassManagerRef = addr
+typedef LLVMTypeRef = addr
+typedef LLVMValueRef = addr
+typedef LLVMTargetDataRef = addr
+typedef LLVMByteOrdering = enum(LLVMBigEndian=0,LLVMLittleEndian=1)
+
+addr LLVMCreateTargetData(string);    ; result LLVMTargetDataRef
+void LLVMAddTargetData(LLVMTargetDataRef,LLVMPassManagerRef);
+string LLVMCopyStringRepOfTargetData(LLVMTargetDataRef);
+addr LLVMByteOrder(LLVMTargetDataRef);    ; result LLVMByteOrdering
+uint LLVMPointerSize(LLVMTargetDataRef);
+addr LLVMIntPtrType(LLVMTargetDataRef);    ; result LLVMTypeRef
+ulong LLVMSizeOfTypeInBits(LLVMTargetDataRef, LLVMTypeRef);
+ulong LLVMStoreSizeOfType(LLVMTargetDataRef, LLVMTypeRef);
+ulong LLVMABISizeOfType(LLVMTargetDataRef, LLVMTypeRef);
+uint LLVMABIAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
+uint LLVMCallFrameAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
+uint LLVMPreferredAlignmentOfType(LLVMTargetDataRef, LLVMTypeRef);
+uint LLVMPreferredAlignmentOfGlobal(LLVMTargetDataRef,LLVMValueRef);
+uint LLVMElementAtOffset(LLVMTargetDataRef, LLVMTypeRef, ulong);
+ulong LLVMOffsetOfElement(LLVMTargetDataRef, LLVMTypeRef, uint);
+void LLVMInvalidateStructLayout(LLVMTargetDataRef, LLVMTypeRef);
+void LLVMDisposeTargetData(LLVMTargetDataRef);
+
+
+; Transforms/IPO.h
+void LLVMAddArgumentPromotionPass(LLVMPassManagerRef);
+void LLVMAddConstantMergePass(LLVMPassManagerRef);
+void LLVMAddDeadArgEliminationPass(LLVMPassManagerRef);
+void LLVMAddDeadTypeEliminationPass(LLVMPassManagerRef);
+void LLVMAddFunctionAttrsPass(LLVMPassManagerRef);
+void LLVMAddFunctionInliningPass(LLVMPassManagerRef);
+void LLVMAddGlobalDCEPass(LLVMPassManagerRef);
+void LLVMAddGlobalOptimizerPass(LLVMPassManagerRef);
+void LLVMAddIPConstantPropagationPass(LLVMPassManagerRef);
+void LLVMAddLowerSetJmpPass(LLVMPassManagerRef);
+void LLVMAddPruneEHPass(LLVMPassManagerRef);
+void LLVMAddIPSCCPPass(LLVMPassManagerRef);
+void LLVMAddInternalizePass(LLVMPassManagerRef, uint);
+void LLVMAddStripDeadPrototypesPass(LLVMPassManagerRef);
+void LLVMAddStripSymbolsPass(LLVMPassManagerRef);
+
+; Transforms/Scalar.h
+void LLVMAddAggressiveDCEPass(LLVMPassManagerRef);
+void LLVMAddCFGSimplificationPass(LLVMPassManagerRef);
+void LLVMAddDeadStoreEliminationPass(LLVMPassManagerRef);
+void LLVMAddGVNPass(LLVMPassManagerRef);
+void LLVMAddIndVarSimplifyPass(LLVMPassManagerRef);
+void LLVMAddInstructionCombiningPass(LLVMPassManagerRef);
+void LLVMAddJumpThreadingPass(LLVMPassManagerRef);
+void LLVMAddLICMPass(LLVMPassManagerRef);
+void LLVMAddLoopDeletionPass(LLVMPassManagerRef);
+void LLVMAddLoopIndexSplitPass(LLVMPassManagerRef);
+void LLVMAddLoopRotatePass(LLVMPassManagerRef);
+void LLVMAddLoopUnrollPass(LLVMPassManagerRef);
+void LLVMAddLoopUnswitchPass(LLVMPassManagerRef);
+void LLVMAddMemCpyOptPass(LLVMPassManagerRef);
+void LLVMAddPromoteMemoryToRegisterPass(LLVMPassManagerRef);
+void LLVMAddReassociatePass(LLVMPassManagerRef);
+void LLVMAddSCCPPass(LLVMPassManagerRef);
+void LLVMAddScalarReplAggregatesPass(LLVMPassManagerRef);
+void LLVMAddScalarReplAggregatesPassWithThreshold(LLVMPassManagerRef, int);
+void LLVMAddSimplifyLibCallsPass(LLVMPassManagerRef);
+void LLVMAddTailCallEliminationPass(LLVMPassManagerRef);
+void LLVMAddConstantPropagationPass(LLVMPassManagerRef);
+void LLVMAddDemoteMemoryToRegisterPass(LLVMPassManagerRef);
+void LLVMAddVerifierPass(LLVMPassManagerRef);
+
+
+; Core.h
+
+typedef LLVMContextRef = addr
+typedef LLVMModuleRef = addr
+typedef LLVMTypeRef = addr
+typedef LLVMTypeHandleRef = addr
+typedef LLVMValueRef = addr
+typedef LLVMBasicBlockRef = addr
+typedef LLVMBuilderRef = addr
+typedef LLVMModuleProviderRef = addr
+typedef LLVMMemoryBufferRef = addr
+typedef LLVMPassManagerRef = addr
+typedef LLVMUseRef = addr
+
+typedef LLVMAttribute = enum (LLVMZExtAttribute = 1, LLVMSExtAttribute = 2, LLVMNoReturnAttribute = 4, LLVMInRegAttribute = 8, LLVMStructRetAttribute = 16, LLVMNoUnwindAttribute = 32, LLVMNoAliasAttribute = 64, LLVMByValAttribute = 128, LLVMNestAttribute = 256, LLVMReadNoneAttribute = 512, LLVMReadOnlyAttribute = 1024, LLVMNoInlineAttribute = 2048, LLVMAlwaysInlineAttribute = 4096, LLVMOptimizeForSizeAttribute = 8192, LLVMStackProtectAttribute = 16384, LLVMStackProtectReqAttribute = 32768, LLVMAlignment = 2031616, LLVMNoCaptureAttribute = 2097152, LLVMNoRedZoneAttribute = 4194304, LLVMNoImplicitFloatAttribute = 8388608, LLVMNakedAttribute = 16777216, LLVMInlineHintAttribute = 33554432, LLVMStackAlignment = 67108864)
+
+typedef LLVMOpcode = enum (LLVMRet = 1, LLVMBr = 2, LLVMSwitch = 3, LLVMIndirectBr = 4, LLVMInvoke = 5, LLVMUnwind = 6, LLVMUnreachable = 7, LLVMAdd = 8, LLVMFAdd = 9, LLVMSub = 10, LLVMFSub = 11, LLVMMul = 12, LLVMFMul = 13, LLVMUDiv = 14, LLVMSDiv = 15, LLVMFDiv = 16, LLVMURem = 17, LLVMSRem = 18, LLVMFRem = 19, LLVMShl = 20, LLVMLShr = 21, LLVMAShr = 22, LLVMAnd = 23, LLVMOr = 24, LLVMXor = 25, LLVMAlloca = 26, LLVMLoad = 27, LLVMStore = 28, LLVMGetElementPtr = 29, LLVMTrunc = 30, LLVMZExt = 31, LLVMSExt = 32, LLVMFPToUI = 33, LLVMFPToSI = 34, LLVMUIToFP = 35, LLVMSIToFP = 36, LLVMFPTrunc = 37, LLVMFPExt = 38, LLVMPtrToInt = 39, LLVMIntToPtr = 40, LLVMBitCast = 41, LLVMICmp = 42, LLVMFCmp = 43, LLVMPHI = 44, LLVMCall = 45, LLVMSelect = 46, LLVMVAArg = 49, LLVMExtractElement = 50, LLVMInsertElement = 51, LLVMShuffleVector = 52, LLVMExtractValue = 53, LLVMInsertValue = 54)
+
+typedef LLVMTypeKind = enum (LLVMVoidTypeKind = 0, LLVMFloatTypeKind = 1, LLVMDoubleTypeKind = 2, LLVMX86_FP80TypeKind = 3, LLVMFP128TypeKind = 4, LLVMPPC_FP128TypeKind = 5, LLVMLabelTypeKind = 6, LLVMIntegerTypeKind = 7, LLVMFunctionTypeKind = 8, LLVMStructTypeKind = 9, LLVMArrayTypeKind = 10, LLVMPointerTypeKind = 11, LLVMOpaqueTypeKind = 12, LLVMVectorTypeKind = 13, LLVMMetadataTypeKind = 14)
+
+typedef LLVMLinkage = enum (LLVMExternalLinkage = 0, LLVMAvailableExternallyLinkage = 1, LLVMLinkOnceAnyLinkage = 2, LLVMLinkOnceODRLinkage = 3, LLVMWeakAnyLinkage = 4, LLVMWeakODRLinkage = 5, LLVMAppendingLinkage = 6, LLVMInternalLinkage = 7, LLVMPrivateLinkage = 8, LLVMDLLImportLinkage = 9, LLVMDLLExportLinkage = 10, LLVMExternalWeakLinkage = 11, LLVMGhostLinkage = 12, LLVMCommonLinkage = 13, LLVMLinkerPrivateLinkage = 14, LLVMLinkerPrivateWeakLinkage = 15, LLVMLinkerPrivateWeakDefAutoLinkage = 16)
+
+typedef LLVMVisibility = enum (LLVMDefaultVisibility = 0, LLVMHiddenVisibility = 1, LLVMProtectedVisibility = 2)
+
+typedef LLVMCallConv = enum (LLVMCCallConv = 0, LLVMFastCallConv = 8, LLVMColdCallConv = 9, LLVMX86StdcallCallConv = 64, LLVMX86FastcallCallConv = 65)
+
+typedef LLVMIntPredicate = enum (LLVMIntEQ = 32, LLVMIntNE = 33, LLVMIntUGT = 34, LLVMIntUGE = 35, LLVMIntULT = 36, LLVMIntULE = 37, LLVMIntSGT = 38, LLVMIntSGE = 39, LLVMIntSLT = 40, LLVMIntSLE = 41)
+
+typedef LLVMRealPredicate = enum (LLVMRealPredicateFalse = 0, LLVMRealOEQ = 1, LLVMRealOGT = 2, LLVMRealOGE = 3, LLVMRealOLT = 4, LLVMRealOLE = 5, LLVMRealONE = 6, LLVMRealORD = 7, LLVMRealUNO = 8, LLVMRealUEQ = 9, LLVMRealUGT = 10, LLVMRealUGE = 11, LLVMRealULT = 12, LLVMRealULE = 13, LLVMRealUNE = 14, LLVMRealPredicateTrue = 15)
+
+
+
+void LLVMDisposeMessage(string);
+
+
+addr LLVMContextCreate(void);    ; result LLVMContextRef
+addr LLVMGetGlobalContext(void);    ; result LLVMContextRef
+void LLVMContextDispose(LLVMContextRef);
+
+uint LLVMGetMDKindIDInContext(LLVMContextRef, string, uint);
+uint LLVMGetMDKindID(string, uint);
+
+addr LLVMModuleCreateWithName(string);    ; result LLVMModuleRef
+addr LLVMModuleCreateWithNameInContext(string, LLVMContextRef);    ; result LLVMModuleRef
+
+void LLVMDisposeModule(LLVMModuleRef);
+
+string LLVMGetDataLayout(LLVMModuleRef);
+void LLVMSetDataLayout(LLVMModuleRef, string);
+
+string LLVMGetTarget(LLVMModuleRef);
+void LLVMSetTarget(LLVMModuleRef, string);
+
+uint LLVMAddTypeName(LLVMModuleRef, string, LLVMTypeRef);    ; result LLVMBool
+void LLVMDeleteTypeName(LLVMModuleRef, string);
+addr LLVMGetTypeByName(LLVMModuleRef, string);    ; result LLVMTypeRef
+
+void LLVMDumpModule(LLVMModuleRef);
+
+void LLVMSetModuleInlineAsm(LLVMModuleRef, string);
+
+
+addr LLVMGetTypeKind(LLVMTypeRef);    ; result LLVMTypeKind
+
+addr LLVMGetTypeContext(LLVMTypeRef);    ; result LLVMContextRef
+
+addr LLVMInt1TypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+addr LLVMInt8TypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+addr LLVMInt16TypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+addr LLVMInt32TypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+addr LLVMInt64TypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+addr LLVMIntTypeInContext(LLVMContextRef, uint);    ; result LLVMTypeRef
+
+addr LLVMInt1Type(void);    ; result LLVMTypeRef
+addr LLVMInt8Type(void);    ; result LLVMTypeRef
+addr LLVMInt16Type(void);    ; result LLVMTypeRef
+addr LLVMInt32Type(void);    ; result LLVMTypeRef
+addr LLVMInt64Type(void);    ; result LLVMTypeRef
+addr LLVMIntType(uint);    ; result LLVMTypeRef
+uint LLVMGetIntTypeWidth(LLVMTypeRef);
+
+addr LLVMFloatTypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+addr LLVMDoubleTypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+addr LLVMX86FP80TypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+addr LLVMFP128TypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+addr LLVMPPCFP128TypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+
+addr LLVMFloatType(void);    ; result LLVMTypeRef
+addr LLVMDoubleType(void);    ; result LLVMTypeRef
+addr LLVMX86FP80Type(void);    ; result LLVMTypeRef
+addr LLVMFP128Type(void);    ; result LLVMTypeRef
+addr LLVMPPCFP128Type(void);    ; result LLVMTypeRef
+
+addr LLVMFunctionType(LLVMTypeRef, array(LLVMTypeRef,arg3)*, uint, LLVMBool);    ; result LLVMTypeRef
+uint LLVMIsFunctionVarArg(LLVMTypeRef);    ; result LLVMBool
+addr LLVMGetReturnType(LLVMTypeRef);    ; result LLVMTypeRef
+uint LLVMCountParamTypes(LLVMTypeRef);
+void LLVMGetParamTypes(LLVMTypeRef, LLVMTypeRef*);
+
+addr LLVMStructTypeInContext(LLVMContextRef, array(LLVMTypeRef,arg3)*, uint, LLVMBool);    ; result LLVMTypeRef
+addr LLVMStructType(array(LLVMTypeRef,arg2)*, uint, LLVMBool);    ; result LLVMTypeRef
+uint LLVMCountStructElementTypes(LLVMTypeRef);
+void LLVMGetStructElementTypes(LLVMTypeRef, LLVMTypeRef*);
+uint LLVMIsPackedStruct(LLVMTypeRef);    ; result LLVMBool
+
+addr LLVMArrayType(LLVMTypeRef, uint);    ; result LLVMTypeRef
+addr LLVMPointerType(LLVMTypeRef, uint);    ; result LLVMTypeRef
+addr LLVMVectorType(LLVMTypeRef, uint);    ; result LLVMTypeRef
+
+addr LLVMGetElementType(LLVMTypeRef);    ; result LLVMTypeRef
+uint LLVMGetArrayLength(LLVMTypeRef);
+uint LLVMGetPointerAddressSpace(LLVMTypeRef);
+uint LLVMGetVectorSize(LLVMTypeRef);
+
+addr LLVMVoidTypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+addr LLVMLabelTypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+addr LLVMOpaqueTypeInContext(LLVMContextRef);    ; result LLVMTypeRef
+
+addr LLVMVoidType(void);    ; result LLVMTypeRef
+addr LLVMLabelType(void);    ; result LLVMTypeRef
+addr LLVMOpaqueType(void);    ; result LLVMTypeRef
+
+addr LLVMCreateTypeHandle(LLVMTypeRef);    ; result LLVMTypeHandleRef
+void LLVMRefineType(LLVMTypeRef, LLVMTypeRef);
+addr LLVMResolveTypeHandle(LLVMTypeHandleRef);    ; result LLVMTypeRef
+void LLVMDisposeTypeHandle(LLVMTypeHandleRef);
+
+
+addr LLVMTypeOf(LLVMValueRef);    ; result LLVMTypeRef
+string LLVMGetValueName(LLVMValueRef);
+void LLVMSetValueName(LLVMValueRef, string);
+void LLVMDumpValue(LLVMValueRef);
+void LLVMReplaceAllUsesWith(LLVMValueRef, LLVMValueRef);
+int LLVMHasMetadata(LLVMValueRef);
+addr LLVMGetMetadata(LLVMValueRef, uint);    ; result LLVMValueRef
+void LLVMSetMetadata(LLVMValueRef, uint, LLVMValueRef);
+
+addr LLVMGetFirstUse(LLVMValueRef);    ; result LLVMUseRef
+addr LLVMGetNextUse(LLVMUseRef);    ; result LLVMUseRef
+addr LLVMGetUser(LLVMUseRef);    ; result LLVMValueRef
+addr LLVMGetUsedValue(LLVMUseRef);    ; result LLVMValueRef
+
+addr LLVMGetOperand(LLVMValueRef, uint);    ; result LLVMValueRef
+void LLVMSetOperand(LLVMValueRef, uint, LLVMValueRef);
+int LLVMGetNumOperands(LLVMValueRef);
+
+addr LLVMConstNull(LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstAllOnes(LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMGetUndef(LLVMTypeRef);    ; result LLVMValueRef
+uint LLVMIsConstant(LLVMValueRef);    ; result LLVMBool
+uint LLVMIsNull(LLVMValueRef);    ; result LLVMBool
+uint LLVMIsUndef(LLVMValueRef);    ; result LLVMBool
+addr LLVMConstPointerNull(LLVMTypeRef);    ; result LLVMValueRef
+
+addr LLVMMDStringInContext(LLVMContextRef, string, uint);    ; result LLVMValueRef
+addr LLVMMDString(string, uint);    ; result LLVMValueRef
+addr LLVMMDNodeInContext(LLVMContextRef, array(LLVMValueRef,arg3)*, uint);    ; result LLVMValueRef
+addr LLVMMDNode(array(LLVMValueRef,arg2)*, uint);    ; result LLVMValueRef
+
+addr LLVMConstInt(LLVMTypeRef, ulong, LLVMBool);    ; result LLVMValueRef
+addr LLVMConstIntOfString(LLVMTypeRef, string, short);    ; result LLVMValueRef
+addr LLVMConstIntOfStringAndSize(LLVMTypeRef, string, uint, short);    ; result LLVMValueRef
+addr LLVMConstReal(LLVMTypeRef, double);    ; result LLVMValueRef
+addr LLVMConstRealOfString(LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMConstRealOfStringAndSize(LLVMTypeRef, string, uint);    ; result LLVMValueRef
+ulong LLVMConstIntGetZExtValue(LLVMValueRef);
+long LLVMConstIntGetSExtValue(LLVMValueRef);
+
+
+addr LLVMConstStringInContext(LLVMContextRef, string, uint, LLVMBool);    ; result LLVMValueRef
+addr LLVMConstStructInContext(LLVMContextRef, array(LLVMValueRef,arg3)*, uint, LLVMBool);    ; result LLVMValueRef
+
+addr LLVMConstString(string, uint, LLVMBool);    ; result LLVMValueRef
+addr LLVMConstArray(LLVMTypeRef, array(LLVMValueRef,arg3)*, uint);    ; result LLVMValueRef
+addr LLVMConstStruct(array(LLVMValueRef,arg2)*, uint, LLVMBool);    ; result LLVMValueRef
+addr LLVMConstVector(array(LLVMValueRef,arg2)*, uint);    ; result LLVMValueRef
+
+addr LLVMGetConstOpcode(LLVMValueRef);    ; result LLVMOpcode
+addr LLVMAlignOf(LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMSizeOf(LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstNeg(LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstNSWNeg(LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstNUWNeg(LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstFNeg(LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstNot(LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstAdd(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstNSWAdd(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstNUWAdd(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstFAdd(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstSub(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstNSWSub(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstNUWSub(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstFSub(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstMul(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstNSWMul(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstNUWMul(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstFMul(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstUDiv(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstSDiv(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstExactSDiv(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstFDiv(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstURem(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstSRem(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstFRem(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstAnd(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstOr(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstXor(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstICmp(LLVMIntPredicate, LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstFCmp(LLVMRealPredicate, LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstShl(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstLShr(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstAShr(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstGEP(LLVMValueRef, array(LLVMValueRef,arg3)*, uint);    ; result LLVMValueRef
+addr LLVMConstInBoundsGEP(LLVMValueRef, array(LLVMValueRef,arg3)*, uint);    ; result LLVMValueRef
+addr LLVMConstTrunc(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstSExt(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstZExt(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstFPTrunc(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstFPExt(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstUIToFP(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstSIToFP(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstFPToUI(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstFPToSI(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstPtrToInt(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstIntToPtr(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstBitCast(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstZExtOrBitCast(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstSExtOrBitCast(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstTruncOrBitCast(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstPointerCast(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstIntCast(LLVMValueRef, LLVMTypeRef, LLVMBool);    ; result LLVMValueRef
+addr LLVMConstFPCast(LLVMValueRef, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMConstSelect(LLVMValueRef, LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstExtractElement(LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstInsertElement(LLVMValueRef, LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstShuffleVector(LLVMValueRef, LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMConstExtractValue(LLVMValueRef, array(uint,arg3)*, uint);    ; result LLVMValueRef
+addr LLVMConstInsertValue(LLVMValueRef, LLVMValueRef, array(uint,arg4)*, uint);    ; result LLVMValueRef
+addr LLVMConstInlineAsm(LLVMTypeRef, string, string, LLVMBool, LLVMBool);    ; result LLVMValueRef
+addr LLVMBlockAddress(LLVMValueRef, LLVMBasicBlockRef);    ; result LLVMValueRef
+
+addr LLVMGetGlobalParent(LLVMValueRef);    ; result LLVMModuleRef
+uint LLVMIsDeclaration(LLVMValueRef);    ; result LLVMBool
+addr LLVMGetLinkage(LLVMValueRef);    ; result LLVMLinkage
+void LLVMSetLinkage(LLVMValueRef, LLVMLinkage);
+string LLVMGetSection(LLVMValueRef);
+void LLVMSetSection(LLVMValueRef, string);
+addr LLVMGetVisibility(LLVMValueRef);    ; result LLVMVisibility
+void LLVMSetVisibility(LLVMValueRef, LLVMVisibility);
+uint LLVMGetAlignment(LLVMValueRef);
+void LLVMSetAlignment(LLVMValueRef, uint);
+
+addr LLVMAddGlobal(LLVMModuleRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMAddGlobalInAddressSpace(LLVMModuleRef, LLVMTypeRef, string, uint);    ; result LLVMValueRef
+addr LLVMGetNamedGlobal(LLVMModuleRef, string);    ; result LLVMValueRef
+addr LLVMGetFirstGlobal(LLVMModuleRef);    ; result LLVMValueRef
+addr LLVMGetLastGlobal(LLVMModuleRef);    ; result LLVMValueRef
+addr LLVMGetNextGlobal(LLVMValueRef);    ; result LLVMValueRef
+addr LLVMGetPreviousGlobal(LLVMValueRef);    ; result LLVMValueRef
+void LLVMDeleteGlobal(LLVMValueRef);
+addr LLVMGetInitializer(LLVMValueRef);    ; result LLVMValueRef
+void LLVMSetInitializer(LLVMValueRef, LLVMValueRef);
+uint LLVMIsThreadLocal(LLVMValueRef);    ; result LLVMBool
+void LLVMSetThreadLocal(LLVMValueRef, LLVMBool);
+uint LLVMIsGlobalConstant(LLVMValueRef);    ; result LLVMBool
+void LLVMSetGlobalConstant(LLVMValueRef, LLVMBool);
+
+addr LLVMAddAlias(LLVMModuleRef, LLVMTypeRef, LLVMValueRef, string);    ; result LLVMValueRef
+
+addr LLVMAddFunction(LLVMModuleRef, string, LLVMTypeRef);    ; result LLVMValueRef
+addr LLVMGetNamedFunction(LLVMModuleRef, string);    ; result LLVMValueRef
+addr LLVMGetFirstFunction(LLVMModuleRef);    ; result LLVMValueRef
+addr LLVMGetLastFunction(LLVMModuleRef);    ; result LLVMValueRef
+addr LLVMGetNextFunction(LLVMValueRef);    ; result LLVMValueRef
+addr LLVMGetPreviousFunction(LLVMValueRef);    ; result LLVMValueRef
+void LLVMDeleteFunction(LLVMValueRef);
+uint LLVMGetIntrinsicID(LLVMValueRef);
+uint LLVMGetFunctionCallConv(LLVMValueRef);
+void LLVMSetFunctionCallConv(LLVMValueRef, uint);
+string LLVMGetGC(LLVMValueRef);
+void LLVMSetGC(LLVMValueRef, string);
+void LLVMAddFunctionAttr(LLVMValueRef, LLVMAttribute);
+addr LLVMGetFunctionAttr(LLVMValueRef);    ; result LLVMAttribute
+void LLVMRemoveFunctionAttr(LLVMValueRef, LLVMAttribute);
+
+uint LLVMCountParams(LLVMValueRef);
+void LLVMGetParams(LLVMValueRef, LLVMValueRef*);
+addr LLVMGetParam(LLVMValueRef, uint);    ; result LLVMValueRef
+addr LLVMGetParamParent(LLVMValueRef);    ; result LLVMValueRef
+addr LLVMGetFirstParam(LLVMValueRef);    ; result LLVMValueRef
+addr LLVMGetLastParam(LLVMValueRef);    ; result LLVMValueRef
+addr LLVMGetNextParam(LLVMValueRef);    ; result LLVMValueRef
+addr LLVMGetPreviousParam(LLVMValueRef);    ; result LLVMValueRef
+void LLVMAddAttribute(LLVMValueRef, LLVMAttribute);
+void LLVMRemoveAttribute(LLVMValueRef, LLVMAttribute);
+addr LLVMGetAttribute(LLVMValueRef);    ; result LLVMAttribute
+void LLVMSetParamAlignment(LLVMValueRef, uint);
+
+addr LLVMBasicBlockAsValue(LLVMBasicBlockRef);    ; result LLVMValueRef
+uint LLVMValueIsBasicBlock(LLVMValueRef);    ; result LLVMBool
+addr LLVMValueAsBasicBlock(LLVMValueRef);    ; result LLVMBasicBlockRef
+addr LLVMGetBasicBlockParent(LLVMBasicBlockRef);    ; result LLVMValueRef
+uint LLVMCountBasicBlocks(LLVMValueRef);
+void LLVMGetBasicBlocks(LLVMValueRef, LLVMBasicBlockRef*);
+addr LLVMGetFirstBasicBlock(LLVMValueRef);    ; result LLVMBasicBlockRef
+addr LLVMGetLastBasicBlock(LLVMValueRef);    ; result LLVMBasicBlockRef
+addr LLVMGetNextBasicBlock(LLVMBasicBlockRef);    ; result LLVMBasicBlockRef
+addr LLVMGetPreviousBasicBlock(LLVMBasicBlockRef);    ; result LLVMBasicBlockRef
+addr LLVMGetEntryBasicBlock(LLVMValueRef);    ; result LLVMBasicBlockRef
+
+addr LLVMAppendBasicBlockInContext(LLVMContextRef, LLVMValueRef, string);    ; result LLVMBasicBlockRef
+addr LLVMInsertBasicBlockInContext(LLVMContextRef, LLVMBasicBlockRef, string);    ; result LLVMBasicBlockRef
+
+addr LLVMAppendBasicBlock(LLVMValueRef, string);    ; result LLVMBasicBlockRef
+addr LLVMInsertBasicBlock(LLVMBasicBlockRef, string);    ; result LLVMBasicBlockRef
+void LLVMDeleteBasicBlock(LLVMBasicBlockRef);
+
+void LLVMMoveBasicBlockBefore(LLVMBasicBlockRef, LLVMBasicBlockRef);
+void LLVMMoveBasicBlockAfter(LLVMBasicBlockRef, LLVMBasicBlockRef);
+
+addr LLVMGetInstructionParent(LLVMValueRef);    ; result LLVMBasicBlockRef
+addr LLVMGetFirstInstruction(LLVMBasicBlockRef);    ; result LLVMValueRef
+addr LLVMGetLastInstruction(LLVMBasicBlockRef);    ; result LLVMValueRef
+addr LLVMGetNextInstruction(LLVMValueRef);    ; result LLVMValueRef
+addr LLVMGetPreviousInstruction(LLVMValueRef);    ; result LLVMValueRef
+
+void LLVMSetInstructionCallConv(LLVMValueRef, uint);
+uint LLVMGetInstructionCallConv(LLVMValueRef);
+void LLVMAddInstrAttribute(LLVMValueRef, uint, LLVMAttribute);
+void LLVMRemoveInstrAttribute(LLVMValueRef, uint, LLVMAttribute);
+void LLVMSetInstrParamAlignment(LLVMValueRef, uint, uint);
+
+uint LLVMIsTailCall(LLVMValueRef);    ; result LLVMBool
+void LLVMSetTailCall(LLVMValueRef, LLVMBool);
+
+void LLVMAddIncoming(LLVMValueRef, array(LLVMValueRef,arg4)*, array(LLVMBasicBlockRef,arg4)*, uint);
+uint LLVMCountIncoming(LLVMValueRef);
+addr LLVMGetIncomingValue(LLVMValueRef, uint);    ; result LLVMValueRef
+addr LLVMGetIncomingBlock(LLVMValueRef, uint);    ; result LLVMBasicBlockRef
+
+
+addr LLVMCreateBuilderInContext(LLVMContextRef);    ; result LLVMBuilderRef
+addr LLVMCreateBuilder(void);    ; result LLVMBuilderRef
+void LLVMPositionBuilder(LLVMBuilderRef, LLVMBasicBlockRef, LLVMValueRef);
+void LLVMPositionBuilderBefore(LLVMBuilderRef, LLVMValueRef);
+void LLVMPositionBuilderAtEnd(LLVMBuilderRef, LLVMBasicBlockRef);
+addr LLVMGetInsertBlock(LLVMBuilderRef);    ; result LLVMBasicBlockRef
+void LLVMClearInsertionPosition(LLVMBuilderRef);
+void LLVMInsertIntoBuilder(LLVMBuilderRef, LLVMValueRef);
+void LLVMInsertIntoBuilderWithName(LLVMBuilderRef, LLVMValueRef, string);
+void LLVMDisposeBuilder(LLVMBuilderRef);
+
+void LLVMSetCurrentDebugLocation(LLVMBuilderRef, LLVMValueRef);
+addr LLVMGetCurrentDebugLocation(LLVMBuilderRef);    ; result LLVMValueRef
+void LLVMSetInstDebugLocation(LLVMBuilderRef, LLVMValueRef);
+
+addr LLVMBuildRetVoid(LLVMBuilderRef);    ; result LLVMValueRef
+addr LLVMBuildRet(LLVMBuilderRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMBuildAggregateRet(LLVMBuilderRef, array(LLVMValueRef,arg3)*, uint);    ; result LLVMValueRef
+addr LLVMBuildBr(LLVMBuilderRef, LLVMBasicBlockRef);    ; result LLVMValueRef
+addr LLVMBuildCondBr(LLVMBuilderRef, LLVMValueRef, LLVMBasicBlockRef, LLVMBasicBlockRef);    ; result LLVMValueRef
+addr LLVMBuildSwitch(LLVMBuilderRef, LLVMValueRef, LLVMBasicBlockRef, uint);    ; result LLVMValueRef
+addr LLVMBuildIndirectBr(LLVMBuilderRef, LLVMValueRef, uint);    ; result LLVMValueRef
+addr LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef, array(LLVMValueRef,arg4)*, uint, LLVMBasicBlockRef, LLVMBasicBlockRef, string);    ; result LLVMValueRef
+addr LLVMBuildUnwind(LLVMBuilderRef);    ; result LLVMValueRef
+addr LLVMBuildUnreachable(LLVMBuilderRef);    ; result LLVMValueRef
+
+void LLVMAddCase(LLVMValueRef, LLVMValueRef, LLVMBasicBlockRef);
+
+void LLVMAddDestination(LLVMValueRef, LLVMBasicBlockRef);
+
+addr LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildNSWAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildNUWAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildFAdd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildSub(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildNSWSub(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildNUWSub(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildFSub(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildNSWMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildNUWMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildFMul(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildUDiv(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildSDiv(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildExactSDiv(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildFDiv(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildURem(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildSRem(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildFRem(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildShl(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildLShr(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildAShr(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildAnd(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildOr(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildXor(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildBinOp(LLVMBuilderRef, LLVMOpcode, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildNeg(LLVMBuilderRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildNSWNeg(LLVMBuilderRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildNUWNeg(LLVMBuilderRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildFNeg(LLVMBuilderRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildNot(LLVMBuilderRef, LLVMValueRef, string);    ; result LLVMValueRef
+
+addr LLVMBuildMalloc(LLVMBuilderRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildArrayMalloc(LLVMBuilderRef, LLVMTypeRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildAlloca(LLVMBuilderRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildArrayAlloca(LLVMBuilderRef, LLVMTypeRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildFree(LLVMBuilderRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMBuildLoad(LLVMBuilderRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildStore(LLVMBuilderRef, LLVMValueRef, LLVMValueRef);    ; result LLVMValueRef
+addr LLVMBuildGEP(LLVMBuilderRef, LLVMValueRef, array(LLVMValueRef,arg4)*, uint, string);    ; result LLVMValueRef
+addr LLVMBuildInBoundsGEP(LLVMBuilderRef, LLVMValueRef, array(LLVMValueRef,arg4)*, uint, string);    ; result LLVMValueRef
+addr LLVMBuildStructGEP(LLVMBuilderRef, LLVMValueRef, uint, string);    ; result LLVMValueRef
+addr LLVMBuildGlobalString(LLVMBuilderRef, string, string);    ; result LLVMValueRef
+addr LLVMBuildGlobalStringPtr(LLVMBuilderRef, string, string);    ; result LLVMValueRef
+
+addr LLVMBuildTrunc(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildZExt(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildSExt(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildFPToUI(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildFPToSI(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildUIToFP(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildSIToFP(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildFPTrunc(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildFPExt(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildPtrToInt(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildIntToPtr(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildBitCast(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildZExtOrBitCast(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildSExtOrBitCast(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildTruncOrBitCast(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildCast(LLVMBuilderRef, LLVMOpcode, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildPointerCast(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildIntCast(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildFPCast(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+
+addr LLVMBuildICmp(LLVMBuilderRef, LLVMIntPredicate, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildFCmp(LLVMBuilderRef, LLVMRealPredicate, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+
+addr LLVMBuildPhi(LLVMBuilderRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildCall(LLVMBuilderRef, LLVMValueRef, array(LLVMValueRef,arg4)*, uint, string);    ; result LLVMValueRef
+addr LLVMBuildSelect(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildVAArg(LLVMBuilderRef, LLVMValueRef, LLVMTypeRef, string);    ; result LLVMValueRef
+addr LLVMBuildExtractElement(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildInsertElement(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildShuffleVector(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildExtractValue(LLVMBuilderRef, LLVMValueRef, uint, string);    ; result LLVMValueRef
+addr LLVMBuildInsertValue(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, uint, string);    ; result LLVMValueRef
+
+addr LLVMBuildIsNull(LLVMBuilderRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildIsNotNull(LLVMBuilderRef, LLVMValueRef, string);    ; result LLVMValueRef
+addr LLVMBuildPtrDiff(LLVMBuilderRef, LLVMValueRef, LLVMValueRef, string);    ; result LLVMValueRef
+
+
+addr LLVMCreateModuleProviderForExistingModule(LLVMModuleRef);    ; result LLVMModuleProviderRef
+
+void LLVMDisposeModuleProvider(LLVMModuleProviderRef);
+
+
+uint LLVMCreateMemoryBufferWithContentsOfFile(string, LLVMMemoryBufferRef*, string*);    ; result LLVMBool
+uint LLVMCreateMemoryBufferWithSTDIN(LLVMMemoryBufferRef*, string*);    ; result LLVMBool
+void LLVMDisposeMemoryBuffer(LLVMMemoryBufferRef);
+
+
+addr LLVMCreatePassManager(void);    ; result LLVMPassManagerRef
+addr LLVMCreateFunctionPassManagerForModule(LLVMModuleRef);    ; result LLVMPassManagerRef
+uint LLVMRunPassManager(LLVMPassManagerRef, LLVMModuleRef);    ; result LLVMBool
+uint LLVMInitializeFunctionPassManager(LLVMPassManagerRef);    ; result LLVMBool
+uint LLVMRunFunctionPassManager(LLVMPassManagerRef, LLVMValueRef);    ; result LLVMBool
+uint LLVMFinalizeFunctionPassManager(LLVMPassManagerRef);    ; result LLVMBool
+void LLVMDisposePassManager(LLVMPassManagerRef);
diff --git a/tool/ltrace.readme b/tool/ltrace.readme
new file mode 100644
--- /dev/null
+++ b/tool/ltrace.readme
@@ -0,0 +1,36 @@
+Ltrace allows you to log the calls from your Haskell program
+into the LLVM C bindings.
+From this log you can reconstruct a C program
+that performs the same actions as your Haskell program.
+I needed this several times in order to create bug tickets
+for http://llvm.org/bugs.
+I hope you do not need it for this purpose, too.
+
+If you want to trace the LLVM calls of a Haskell program Main
+it is essential to build it
+with static calls from Main into Haskell-llvm
+  (that is no -dynamic flag for ghc)
+but dynamic calls from Haskell-llvm to LLVM
+  (-lLLVM-2.8rc  instead of `llvm-config --libs`).
+You should get an executable of around 10 MB size.
+If you link LLVM statically into the executable,
+then ltrace cannot track calls to LLVM at all.
+Such executables are several tens of MB large.
+If you link dynamically to Haskell-llvm,
+then only calls from Main to Haskell-llvm are tracked,
+but not those from Haskell-llvm to LLVM.
+If you are lucky some calls from Main to Haskell-llvm are inlined by GHC,
+and then some calls go directly from Main to LLVM
+and are thus visible for ltrace.
+Such executables are usually quite small
+(for todays norms), about some tens KB.
+You do not have this fine control of compilation
+when compiling with Cabal.
+I think you must call ghc directly like in:
+
+$ ghc -lLLVM-2.8rc -package llvm -O -debug -o main src/Main.hs
+
+
+You can then generate a log of the LLVM calls from Main using:
+
+$ ltrace -F ltrace.config --library=/usr/local/lib/libLLVM-2.8rc.so main
