diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,5 @@
+# CHANGELOG for `binaryen`
+
+## 0.0.1.0
+
+- Initial release.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,28 @@
+Copyright (c) 2018 EURL Tweag
+
+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 Tweag I/O nor the names of other 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.
diff --git a/README.md b/README.md
new file mode 100644
--- /dev/null
+++ b/README.md
@@ -0,0 +1,35 @@
+# Haskell bindings for [binaryen][binaryen]
+
+[Binaryen][binaryen] is a compiler and toolchain infrastructure library for
+WebAssembly, written in C++. This package defines complete bindings to the
+[Binaryen C API][binaryen-api], and can be useful to building WebAssembly
+toolchains in Haskell.
+
+[binaryen]: https://github.com/WebAssembly/binaryen
+[binaryen-api]: https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h
+
+## Versioning
+
+Binaryen evolves fast and can introduce C API changes in every release. Before
+building the Haskell bindings, please check the Binaryen version and make sure
+it's no less than the minimum version listed below.
+
+| Haskell bindings version | Minimum Binaryen version |
+|--------------------------|--------------------------|
+| 0.0.1.0                  | version_91               |
+
+
+## How to build
+
+This package relies on the system-provided Binaryen library. As long as that's
+available, a simple `stack build` or `cabal build` command should work.
+
+`Nix`-based build is also supported. Install [Stack][stack] and [Nix][nix].
+Then,
+
+```shell
+$ stack --nix build
+```
+
+[nix]: https://nixos.org/nix/
+[stack]: https://docs.haskellstack.org/en/stable/README/
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/binaryen.cabal b/binaryen.cabal
new file mode 100644
--- /dev/null
+++ b/binaryen.cabal
@@ -0,0 +1,59 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.33.0.
+--
+-- see: https://github.com/sol/hpack
+--
+-- hash: 36ff73cba099e841c7dc59136556f413d3416a42487b5fb1d1cec6c31367ef83
+
+name:           binaryen
+version:        0.0.1.0
+synopsis:       Haskell bindings to binaryen
+description:    Haskell bindings to [binaryen](https://github.com/WebAssembly/binaryen). Provides complete bindings to the C API, which can be useful for building WebAssembly toolchains in Haskell.
+category:       Compiler
+homepage:       https://github.com/tweag/asterius#readme
+bug-reports:    https://github.com/tweag/asterius/issues
+maintainer:     Shao Cheng <cheng.shao@tweag.io>
+copyright:      (c) 2018 Tweag I/O
+license:        BSD3
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    CHANGELOG.md
+    LICENSE
+    README.md
+
+source-repository head
+  type: git
+  location: https://github.com/tweag/asterius
+
+library
+  exposed-modules:
+      Binaryen
+      Binaryen.Event
+      Binaryen.Export
+      Binaryen.Expression
+      Binaryen.ExpressionId
+      Binaryen.ExternalKind
+      Binaryen.Features
+      Binaryen.Function
+      Binaryen.Global
+      Binaryen.Index
+      Binaryen.Module
+      Binaryen.Op
+      Binaryen.Relooper
+      Binaryen.SideEffects
+      Binaryen.Type
+  other-modules:
+      Paths_binaryen
+  hs-source-dirs:
+      src
+  ghc-options: -Wall
+  c-sources:
+      cbits/wrappers.c
+  extra-libraries:
+      binaryen
+      stdc++
+  build-depends:
+      base <5
+  default-language: Haskell2010
diff --git a/cbits/wrappers.c b/cbits/wrappers.c
new file mode 100644
--- /dev/null
+++ b/cbits/wrappers.c
@@ -0,0 +1,16 @@
+#include <binaryen-c.h>
+
+BinaryenExpressionRef BinaryenConstInt32(BinaryenModuleRef module, int32_t x) { return BinaryenConst(module, BinaryenLiteralInt32(x)); }
+BinaryenExpressionRef BinaryenConstInt64(BinaryenModuleRef module, int64_t x) { return BinaryenConst(module, BinaryenLiteralInt64(x)); }
+BinaryenExpressionRef BinaryenConstFloat32(BinaryenModuleRef module, float x) { return BinaryenConst(module, BinaryenLiteralFloat32(x)); }
+BinaryenExpressionRef BinaryenConstFloat64(BinaryenModuleRef module, double x) { return BinaryenConst(module, BinaryenLiteralFloat64(x)); }
+BinaryenExpressionRef BinaryenConstVec128(BinaryenModuleRef module, const uint8_t x[16]) { return BinaryenConst(module, BinaryenLiteralVec128(x)); }
+BinaryenExpressionRef BinaryenConstFloat32Bits(BinaryenModuleRef module, int32_t x) { return BinaryenConst(module, BinaryenLiteralFloat32Bits(x)); }
+BinaryenExpressionRef BinaryenConstFloat64Bits(BinaryenModuleRef module, int64_t x) { return BinaryenConst(module, BinaryenLiteralFloat64Bits(x)); }
+
+void BinaryenModuleAllocateAndWriteMut(BinaryenModuleRef module, const char* sourceMapUrl, void** binary, size_t* binaryBytes, char** sourceMap) {
+	BinaryenModuleAllocateAndWriteResult r = BinaryenModuleAllocateAndWrite(module, sourceMapUrl);
+	*binary = r.binary;
+	*binaryBytes = r.binaryBytes;
+	*sourceMap = r.sourceMap;
+}
diff --git a/src/Binaryen.hs b/src/Binaryen.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen.hs
@@ -0,0 +1,124 @@
+-- | Global Binaryen state.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+module Binaryen
+  ( module Binaryen,
+    -- * Re-exports
+    Event,
+    Export,
+    Expression,
+    ExpressionId,
+    ExternalKind,
+    Features,
+    Function,
+    Global,
+    Index,
+    Module,
+    Op,
+    Relooper,
+    RelooperBlock,
+    SideEffects,
+    Type,
+  )
+where
+
+import Binaryen.Event (Event(..))
+import Binaryen.Export (Export(..))
+import Binaryen.Expression (Expression(..))
+import Binaryen.ExpressionId (ExpressionId(..))
+import Binaryen.ExternalKind (ExternalKind(..))
+import Binaryen.Features (Features(..))
+import Binaryen.Function (Function(..))
+import Binaryen.Global (Global(..))
+import Binaryen.Index (Index(..))
+import Binaryen.Module (Module(..))
+import Binaryen.Op (Op(..))
+import Binaryen.Relooper (Relooper(..), RelooperBlock(..))
+import Binaryen.SideEffects (SideEffects(..))
+import Binaryen.Type (Type(..))
+import Foreign (Ptr)
+import Foreign.C (CChar(..), CInt(..))
+
+foreign import ccall unsafe "BinaryenGetOptimizeLevel"
+  getOptimizeLevel ::
+    IO CInt
+
+foreign import ccall unsafe "BinaryenSetOptimizeLevel"
+  setOptimizeLevel ::
+    CInt -> IO ()
+
+foreign import ccall unsafe "BinaryenGetShrinkLevel"
+  getShrinkLevel ::
+    IO CInt
+
+foreign import ccall unsafe "BinaryenSetShrinkLevel"
+  setShrinkLevel ::
+    CInt -> IO ()
+
+foreign import ccall unsafe "BinaryenGetDebugInfo"
+  getDebugInfo ::
+    IO CInt
+
+foreign import ccall unsafe "BinaryenSetDebugInfo"
+  setDebugInfo ::
+    CInt -> IO ()
+
+foreign import ccall unsafe "BinaryenGetLowMemoryUnused"
+  getLowMemoryUnused ::
+    IO CInt
+
+foreign import ccall unsafe "BinaryenSetLowMemoryUnused"
+  setLowMemoryUnused ::
+    CInt -> IO ()
+
+foreign import ccall unsafe "BinaryenGetPassArgument"
+  getPassArgument ::
+    Ptr CChar -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenSetPassArgument"
+  setPassArgument ::
+    Ptr CChar -> Ptr CChar -> IO ()
+
+foreign import ccall unsafe "BinaryenClearPassArguments"
+  clearPassArguments ::
+    IO ()
+
+foreign import ccall unsafe "BinaryenGetAlwaysInlineMaxSize"
+  getAlwaysInlineMaxSize ::
+    IO Index
+
+foreign import ccall unsafe "BinaryenSetAlwaysInlineMaxSize"
+  setAlwaysInlineMaxSize ::
+    Index -> IO ()
+
+foreign import ccall unsafe "BinaryenGetFlexibleInlineMaxSize"
+  getFlexibleInlineMaxSize ::
+    IO Index
+
+foreign import ccall unsafe "BinaryenSetFlexibleInlineMaxSize"
+  setFlexibleInlineMaxSize ::
+    Index -> IO ()
+
+foreign import ccall unsafe "BinaryenGetOneCallerInlineMaxSize"
+  getOneCallerInlineMaxSize ::
+    IO Index
+
+foreign import ccall unsafe "BinaryenSetOneCallerInlineMaxSize"
+  setOneCallerInlineMaxSize ::
+    Index -> IO ()
+
+foreign import ccall unsafe "BinaryenSetAPITracing"
+  setAPITracing ::
+    CInt -> IO ()
+
+foreign import ccall unsafe "BinaryenSetColorsEnabled"
+  setColorsEnabled ::
+    CInt -> IO ()
+
+foreign import ccall unsafe "BinaryenAreColorsEnabled"
+  areColorsEnabled ::
+    IO CInt
diff --git a/src/Binaryen/Event.hs b/src/Binaryen/Event.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/Event.hs
@@ -0,0 +1,41 @@
+-- | Events.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.Event where
+
+import Binaryen.Type
+import Foreign (Ptr, Storable)
+import Foreign.C (CChar(..), CInt(..))
+
+newtype Event = Event (Ptr Event)
+  deriving (Eq, Show, Storable)
+
+foreign import ccall unsafe "BinaryenEventGetName"
+  getName ::
+    Event -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenEventGetAttribute"
+  getAttribute ::
+    Event -> IO CInt
+
+foreign import ccall unsafe "BinaryenEventGetParams"
+  getParams ::
+    Event -> IO Type
+
+foreign import ccall unsafe "BinaryenEventGetResults"
+  getResults ::
+    Event -> IO Type
+
+foreign import ccall unsafe "BinaryenEventImportGetModule"
+  importGetModule ::
+    Event -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenEventImportGetBase"
+  eventImportGetBase ::
+    Event -> IO (Ptr CChar)
diff --git a/src/Binaryen/Export.hs b/src/Binaryen/Export.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/Export.hs
@@ -0,0 +1,29 @@
+-- | Exports.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.Export where
+
+import Binaryen.ExternalKind
+import Foreign (Ptr, Storable)
+import Foreign.C (CChar)
+
+newtype Export = Export (Ptr Export)
+  deriving (Eq, Show, Storable)
+
+foreign import ccall unsafe "BinaryenExportGetKind"
+  getKind ::
+    Export -> IO ExternalKind
+
+foreign import ccall unsafe "BinaryenExportGetName"
+  getName ::
+    Export -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenExportGetValue"
+  getValue ::
+    Export -> IO (Ptr CChar)
diff --git a/src/Binaryen/Expression.hs b/src/Binaryen/Expression.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/Expression.hs
@@ -0,0 +1,940 @@
+-- | Expressions.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.Expression where
+
+import Binaryen.ExpressionId
+import Binaryen.Index
+import {-# SOURCE #-} Binaryen.Module
+import Binaryen.Op
+import Binaryen.Type
+import Data.Int (Int8, Int32, Int64)
+import Data.Word (Word32, Word8)
+import Foreign (Ptr, Storable)
+import Foreign.C (CChar(..), CDouble(..), CFloat(..), CInt(..))
+
+newtype Expression = Expression (Ptr Expression)
+  deriving (Eq, Show, Storable)
+
+foreign import ccall unsafe "BinaryenConstInt32"
+  constInt32 ::
+    Module -> Int32 -> IO Expression
+
+foreign import ccall unsafe "BinaryenConstInt64"
+  constInt64 ::
+    Module -> Int64 -> IO Expression
+
+foreign import ccall unsafe "BinaryenConstFloat32"
+  constFloat32 ::
+    Module -> Float -> IO Expression
+
+foreign import ccall unsafe "BinaryenConstFloat64"
+  constFloat64 ::
+    Module -> Double -> IO Expression
+
+foreign import ccall unsafe "BinaryenConstVec128"
+  constVec128 ::
+    Module -> Ptr Word8 -> IO Expression
+
+foreign import ccall unsafe "BinaryenConstFloat32Bits"
+  constFloat32Bits ::
+    Module -> Int32 -> IO Expression
+
+foreign import ccall unsafe "BinaryenConstFloat64Bits"
+  constFloat64Bits ::
+    Module -> Int64 -> IO Expression
+
+foreign import ccall unsafe "BinaryenBlock"
+  block ::
+    Module ->
+    Ptr CChar ->
+    Ptr Expression ->
+    Index ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenIf"
+  if_ ::
+    Module ->
+    Expression ->
+    Expression ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenLoop"
+  loop ::
+    Module ->
+    Ptr CChar ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenBreak"
+  break ::
+    Module ->
+    Ptr CChar ->
+    Expression ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenSwitch"
+  switch ::
+    Module ->
+    Ptr (Ptr CChar) ->
+    Index ->
+    Ptr CChar ->
+    Expression ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenCall"
+  call ::
+    Module ->
+    Ptr CChar ->
+    Ptr Expression ->
+    Index ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenCallIndirect"
+  callIndirect ::
+    Module ->
+    Expression ->
+    Ptr Expression ->
+    Index ->
+    Type ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenReturnCall"
+  returnCall ::
+    Module ->
+    Ptr CChar ->
+    Ptr Expression ->
+    Index ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenReturnCallIndirect"
+  returnCallIndirect ::
+    Module ->
+    Expression ->
+    Ptr Expression ->
+    Index ->
+    Type ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenLocalGet"
+  localGet ::
+    Module ->
+    Index ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenLocalSet"
+  localSet ::
+    Module ->
+    Index ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenLocalTee"
+  localTee ::
+    Module ->
+    Index ->
+    Expression ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenGlobalGet"
+  globalGet ::
+    Module ->
+    Ptr CChar ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenGlobalSet"
+  globalSet ::
+    Module ->
+    Ptr CChar ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenLoad"
+  load ::
+    Module ->
+    Word32 ->
+    Int8 ->
+    Word32 ->
+    Word32 ->
+    Type ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenStore"
+  store ::
+    Module ->
+    Word32 ->
+    Word32 ->
+    Word32 ->
+    Expression ->
+    Expression ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenUnary"
+  unary ::
+    Module ->
+    Op ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenBinary"
+  binary ::
+    Module ->
+    Op ->
+    Expression ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenSelect"
+  select ::
+    Module ->
+    Expression ->
+    Expression ->
+    Expression ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenDrop"
+  drop ::
+    Module ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenReturn"
+  return ::
+    Module ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenHost"
+  host ::
+    Module ->
+    Op ->
+    Ptr CChar ->
+    Ptr Expression ->
+    Index ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenNop"
+  nop ::
+    Module -> IO Expression
+
+foreign import ccall unsafe "BinaryenUnreachable"
+  unreachable ::
+    Module -> IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicLoad"
+  atomicLoad ::
+    Module ->
+    Word32 ->
+    Word32 ->
+    Type ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicStore"
+  atomicStore ::
+    Module ->
+    Word32 ->
+    Word32 ->
+    Expression ->
+    Expression ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicRMW"
+  atomicRMW ::
+    Module ->
+    Op ->
+    Index ->
+    Index ->
+    Expression ->
+    Expression ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicCmpxchg"
+  atomicCmpxchg ::
+    Module ->
+    Index ->
+    Index ->
+    Expression ->
+    Expression ->
+    Expression ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicWait"
+  atomicWait ::
+    Module ->
+    Expression ->
+    Expression ->
+    Expression ->
+    Type ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicNotify"
+  atomicNotify ::
+    Module ->
+    Expression ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicFence"
+  atomicFence ::
+    Module -> IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDExtract"
+  simdExtract ::
+    Module ->
+    Op ->
+    Expression ->
+    Word8 ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDReplace"
+  simdReplace ::
+    Module ->
+    Op ->
+    Expression ->
+    Word8 ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDShuffle"
+  simdShuffle ::
+    Module ->
+    Expression ->
+    Expression ->
+    Ptr Word8 ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDTernary"
+  simdTernary ::
+    Module ->
+    Op ->
+    Expression ->
+    Expression ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDShift"
+  simdShift ::
+    Module ->
+    Op ->
+    Expression ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDLoad"
+  simdLoad ::
+    Module ->
+    Op ->
+    Word32 ->
+    Word32 ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenMemoryInit"
+  memoryInit ::
+    Module ->
+    Word32 ->
+    Expression ->
+    Expression ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenDataDrop"
+  dataDrop ::
+    Module -> Word32 -> IO Expression
+
+foreign import ccall unsafe "BinaryenMemoryCopy"
+  memoryCopy ::
+    Module ->
+    Expression ->
+    Expression ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenMemoryFill"
+  memoryFill ::
+    Module ->
+    Expression ->
+    Expression ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenRefNull"
+  refNull ::
+    Module -> IO Expression
+
+foreign import ccall unsafe "BinaryenRefIsNull"
+  refIsNull ::
+    Module ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenRefFunc"
+  refFunc ::
+    Module -> Ptr CChar -> IO Expression
+
+foreign import ccall unsafe "BinaryenTry"
+  try ::
+    Module ->
+    Expression ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenThrow"
+  throw ::
+    Module ->
+    Ptr CChar ->
+    Ptr Expression ->
+    Index ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenRethrow"
+  rethrow ::
+    Module ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenBrOnExn"
+  brOnExn ::
+    Module ->
+    Ptr CChar ->
+    Ptr CChar ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenPush"
+  push ::
+    Module ->
+    Expression ->
+    IO Expression
+
+foreign import ccall unsafe "BinaryenPop"
+  pop ::
+    Module -> Type -> IO Expression
+
+foreign import ccall unsafe "BinaryenExpressionGetId"
+  getId ::
+    Expression -> IO ExpressionId
+
+foreign import ccall unsafe "BinaryenExpressionGetType"
+  getType ::
+    Expression -> IO Type
+
+foreign import ccall unsafe "BinaryenExpressionPrint"
+  print ::
+    Expression -> IO ()
+
+foreign import ccall unsafe "BinaryenBlockGetName"
+  blockGetName ::
+    Expression -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenBlockGetNumChildren"
+  blockGetNumChildren ::
+    Expression -> IO Index
+
+foreign import ccall unsafe "BinaryenBlockGetChild"
+  blockGetChild ::
+    Expression -> Index -> IO Expression
+
+foreign import ccall unsafe "BinaryenIfGetCondition"
+  ifGetCondition ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenIfGetIfTrue"
+  ifGetIfTrue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenIfGetIfFalse"
+  ifGetIfFalse ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenLoopGetName"
+  loopGetName ::
+    Expression -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenLoopGetBody"
+  loopGetBody ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenBreakGetName"
+  breakGetName ::
+    Expression -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenBreakGetCondition"
+  breakGetCondition ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenBreakGetValue"
+  breakGetValue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSwitchGetNumNames"
+  switchGetNumNames ::
+    Expression -> IO Index
+
+foreign import ccall unsafe "BinaryenSwitchGetName"
+  switchGetName ::
+    Expression -> Index -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenSwitchGetDefaultName"
+  switchGetDefaultName ::
+    Expression -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenSwitchGetCondition"
+  switchGetCondition ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSwitchGetValue"
+  switchGetValue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenCallGetTarget"
+  callGetTarget ::
+    Expression -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenCallGetNumOperands"
+  callGetNumOperands ::
+    Expression -> IO Index
+
+foreign import ccall unsafe "BinaryenCallGetOperand"
+  callGetOperand ::
+    Expression -> Index -> IO Expression
+
+foreign import ccall unsafe "BinaryenCallIndirectGetTarget"
+  callIndirectGetTarget ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenCallIndirectGetNumOperands"
+  callIndirectGetNumOperands ::
+    Expression -> IO Index
+
+foreign import ccall unsafe "BinaryenCallIndirectGetOperand"
+  callIndirectGetOperand ::
+    Expression -> Index -> IO Expression
+
+foreign import ccall unsafe "BinaryenLocalGetGetIndex"
+  localGetGetIndex ::
+    Expression -> IO Index
+
+foreign import ccall unsafe "BinaryenLocalSetIsTee"
+  localSetIsTee ::
+    Expression -> IO CInt
+
+foreign import ccall unsafe "BinaryenLocalSetGetIndex"
+  localSetGetIndex ::
+    Expression -> IO Index
+
+foreign import ccall unsafe "BinaryenLocalSetGetValue"
+  localSetGetValue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenGlobalGetGetName"
+  globalGetGetName ::
+    Expression -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenGlobalSetGetName"
+  globalSetGetName ::
+    Expression -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenGlobalSetGetValue"
+  globalSetGetValue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenHostGetOp"
+  hostGetOp ::
+    Expression -> IO Op
+
+foreign import ccall unsafe "BinaryenHostGetNameOperand"
+  hostGetNameOperand ::
+    Expression -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenHostGetNumOperands"
+  hostGetNumOperands ::
+    Expression -> IO Index
+
+foreign import ccall unsafe "BinaryenHostGetOperand"
+  hostGetOperand ::
+    Expression -> Index -> IO Expression
+
+foreign import ccall unsafe "BinaryenLoadIsAtomic"
+  loadIsAtomic ::
+    Expression -> IO CInt
+
+foreign import ccall unsafe "BinaryenLoadIsSigned"
+  loadIsSigned ::
+    Expression -> IO CInt
+
+foreign import ccall unsafe "BinaryenLoadGetOffset"
+  loadGetOffset ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenLoadGetBytes"
+  loadGetBytes ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenLoadGetAlign"
+  loadGetAlign ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenLoadGetPtr"
+  loadGetPtr ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenStoreIsAtomic"
+  storeIsAtomic ::
+    Expression -> IO CInt
+
+foreign import ccall unsafe "BinaryenStoreGetBytes"
+  storeGetBytes ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenStoreGetOffset"
+  storeGetOffset ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenStoreGetAlign"
+  storeGetAlign ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenStoreGetPtr"
+  storeGetPtr ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenStoreGetValue"
+  storeGetValue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenConstGetValueI32"
+  constGetValueI32 ::
+    Expression -> IO Int32
+
+foreign import ccall unsafe "BinaryenConstGetValueI64"
+  constGetValueI64 ::
+    Expression -> IO Int64
+
+foreign import ccall unsafe "BinaryenConstGetValueI64Low"
+  constGetValueI64Low ::
+    Expression -> IO Int32
+
+foreign import ccall unsafe "BinaryenConstGetValueI64High"
+  constGetValueI64High ::
+    Expression -> IO Int32
+
+foreign import ccall unsafe "BinaryenConstGetValueF32"
+  constGetValueF32 ::
+    Expression -> IO CFloat
+
+foreign import ccall unsafe "BinaryenConstGetValueF64"
+  constGetValueF64 ::
+    Expression -> IO CDouble
+
+foreign import ccall unsafe "BinaryenConstGetValueV128"
+  constGetValueV128 ::
+    Expression -> Ptr Word8 -> IO ()
+
+foreign import ccall unsafe "BinaryenUnaryGetOp"
+  unaryGetOp ::
+    Expression -> IO Op
+
+foreign import ccall unsafe "BinaryenUnaryGetValue"
+  unaryGetValue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenBinaryGetOp"
+  binaryGetOp ::
+    Expression -> IO Op
+
+foreign import ccall unsafe "BinaryenBinaryGetLeft"
+  binaryGetLeft ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenBinaryGetRight"
+  binaryGetRight ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSelectGetIfTrue"
+  selectGetIfTrue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSelectGetIfFalse"
+  selectGetIfFalse ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSelectGetCondition"
+  selectGetCondition ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenDropGetValue"
+  dropGetValue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenReturnGetValue"
+  returnGetValue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicRMWGetOp"
+  atomicRMWGetOp ::
+    Expression -> IO Op
+
+foreign import ccall unsafe "BinaryenAtomicRMWGetBytes"
+  atomicRMWGetBytes ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenAtomicRMWGetOffset"
+  atomicRMWGetOffset ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenAtomicRMWGetPtr"
+  atomicRMWGetPtr ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicRMWGetValue"
+  atomicRMWGetValue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicCmpxchgGetBytes"
+  atomicCmpxchgGetBytes ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenAtomicCmpxchgGetOffset"
+  atomicCmpxchgGetOffset ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenAtomicCmpxchgGetPtr"
+  atomicCmpxchgGetPtr ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicCmpxchgGetExpected"
+  atomicCmpxchgGetExpected ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicCmpxchgGetReplacement"
+  atomicCmpxchgGetReplacement ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicWaitGetPtr"
+  atomicWaitGetPtr ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicWaitGetExpected"
+  atomicWaitGetExpected ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicWaitGetTimeout"
+  atomicWaitGetTimeout ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicWaitGetExpectedType"
+  atomicWaitGetExpectedType ::
+    Expression -> IO Type
+
+foreign import ccall unsafe "BinaryenAtomicNotifyGetPtr"
+  atomicNotifyGetPtr ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicNotifyGetNotifyCount"
+  atomicNotifyGetNotifyCount ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenAtomicFenceGetOrder"
+  atomicFenceGetOrder ::
+    Expression -> IO Word8
+
+foreign import ccall unsafe "BinaryenSIMDExtractGetOp"
+  simdExtractGetOp ::
+    Expression -> IO Op
+
+foreign import ccall unsafe "BinaryenSIMDExtractGetVec"
+  simdExtractGetVec ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDExtractGetIndex"
+  simdExtractGetIndex ::
+    Expression -> IO Word8
+
+foreign import ccall unsafe "BinaryenSIMDReplaceGetOp"
+  simdReplaceGetOp ::
+    Expression -> IO Op
+
+foreign import ccall unsafe "BinaryenSIMDReplaceGetVec"
+  simdReplaceGetVec ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDReplaceGetIndex"
+  simdReplaceGetIndex ::
+    Expression -> IO Word8
+
+foreign import ccall unsafe "BinaryenSIMDReplaceGetValue"
+  simdReplaceGetValue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDShuffleGetLeft"
+  simdShuffleGetLeft ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDShuffleGetRight"
+  simdShuffleGetRight ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDShuffleGetMask"
+  simdShuffleGetMask ::
+    Expression -> Ptr Word8 -> IO ()
+
+foreign import ccall unsafe "BinaryenSIMDTernaryGetOp"
+  simdTernaryGetOp ::
+    Expression -> IO Op
+
+foreign import ccall unsafe "BinaryenSIMDTernaryGetA"
+  simdTernaryGetA ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDTernaryGetB"
+  simdTernaryGetB ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDTernaryGetC"
+  simdTernaryGetC ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDShiftGetOp"
+  simdShiftGetOp ::
+    Expression -> IO Op
+
+foreign import ccall unsafe "BinaryenSIMDShiftGetVec"
+  simdShiftGetVec ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDShiftGetShift"
+  simdShiftGetShift ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenSIMDLoadGetOp"
+  simdLoadGetOp ::
+    Expression -> IO Op
+
+foreign import ccall unsafe "BinaryenSIMDLoadGetOffset"
+  simdLoadGetOffset ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenSIMDLoadGetAlign"
+  simdLoadGetAlign ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenSIMDLoadGetPtr"
+  simdLoadGetPtr ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenMemoryInitGetSegment"
+  memoryInitGetSegment ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenMemoryInitGetDest"
+  memoryInitGetDest ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenMemoryInitGetOffset"
+  memoryInitGetOffset ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenMemoryInitGetSize"
+  memoryInitGetSize ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenDataDropGetSegment"
+  dataDropGetSegment ::
+    Expression -> IO Word32
+
+foreign import ccall unsafe "BinaryenMemoryCopyGetDest"
+  memoryCopyGetDest ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenMemoryCopyGetSource"
+  memoryCopyGetSource ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenMemoryCopyGetSize"
+  memoryCopyGetSize ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenMemoryFillGetDest"
+  memoryFillGetDest ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenMemoryFillGetValue"
+  memoryFillGetValue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenMemoryFillGetSize"
+  memoryFillGetSize ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenRefIsNullGetValue"
+  refIsNullGetValue ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenRefFuncGetFunc"
+  refFuncGetFunc ::
+    Expression -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenTryGetBody"
+  tryGetBody ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenTryGetCatchBody"
+  tryGetCatchBody ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenThrowGetEvent"
+  throwGetEvent ::
+    Expression -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenThrowGetOperand"
+  throwGetOperand ::
+    Expression -> Index -> IO Expression
+
+foreign import ccall unsafe "BinaryenThrowGetNumOperands"
+  throwGetNumOperands ::
+    Expression -> IO Index
+
+foreign import ccall unsafe "BinaryenRethrowGetExnref"
+  rethrowGetExnref ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenBrOnExnGetEvent"
+  brOnExnGetEvent ::
+    Expression -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenBrOnExnGetName"
+  brOnExnGetName ::
+    Expression -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenBrOnExnGetExnref"
+  brOnExnGetExnref ::
+    Expression -> IO Expression
+
+foreign import ccall unsafe "BinaryenPushGetValue"
+  pushGetValue ::
+    Expression -> IO Expression
diff --git a/src/Binaryen/ExpressionId.hs b/src/Binaryen/ExpressionId.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/ExpressionId.hs
@@ -0,0 +1,64 @@
+-- | Expression identifiers.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.ExpressionId where
+
+import Data.Word (Word32)
+import Foreign (Storable)
+
+newtype ExpressionId = ExpressionId Word32
+  deriving (Eq, Show, Storable)
+
+foreign import ccall unsafe "BinaryenInvalidId" invalidId :: ExpressionId
+foreign import ccall unsafe "BinaryenBlockId" blockId :: ExpressionId
+foreign import ccall unsafe "BinaryenIfId" ifId :: ExpressionId
+foreign import ccall unsafe "BinaryenLoopId" loopId :: ExpressionId
+foreign import ccall unsafe "BinaryenBreakId" breakId :: ExpressionId
+foreign import ccall unsafe "BinaryenSwitchId" switchId :: ExpressionId
+foreign import ccall unsafe "BinaryenCallId" callId :: ExpressionId
+foreign import ccall unsafe "BinaryenCallIndirectId" callIndirectId :: ExpressionId
+foreign import ccall unsafe "BinaryenLocalGetId" localGetId :: ExpressionId
+foreign import ccall unsafe "BinaryenLocalSetId" localSetId :: ExpressionId
+foreign import ccall unsafe "BinaryenGlobalGetId" globalGetId :: ExpressionId
+foreign import ccall unsafe "BinaryenGlobalSetId" globalSetId :: ExpressionId
+foreign import ccall unsafe "BinaryenLoadId" loadId :: ExpressionId
+foreign import ccall unsafe "BinaryenStoreId" storeId :: ExpressionId
+foreign import ccall unsafe "BinaryenConstId" constId :: ExpressionId
+foreign import ccall unsafe "BinaryenUnaryId" unaryId :: ExpressionId
+foreign import ccall unsafe "BinaryenBinaryId" binaryId :: ExpressionId
+foreign import ccall unsafe "BinaryenSelectId" selectId :: ExpressionId
+foreign import ccall unsafe "BinaryenDropId" dropId :: ExpressionId
+foreign import ccall unsafe "BinaryenReturnId" returnId :: ExpressionId
+foreign import ccall unsafe "BinaryenHostId" hostId :: ExpressionId
+foreign import ccall unsafe "BinaryenNopId" nopId :: ExpressionId
+foreign import ccall unsafe "BinaryenUnreachableId" unreachableId :: ExpressionId
+foreign import ccall unsafe "BinaryenAtomicCmpxchgId" atomicCmpxchgId :: ExpressionId
+foreign import ccall unsafe "BinaryenAtomicRMWId" atomicRMWId :: ExpressionId
+foreign import ccall unsafe "BinaryenAtomicWaitId" atomicWaitId :: ExpressionId
+foreign import ccall unsafe "BinaryenAtomicNotifyId" atomicNotifyId :: ExpressionId
+foreign import ccall unsafe "BinaryenAtomicFenceId" atomicFenceId :: ExpressionId
+foreign import ccall unsafe "BinaryenSIMDExtractId" simdExtractId :: ExpressionId
+foreign import ccall unsafe "BinaryenSIMDReplaceId" simdReplaceId :: ExpressionId
+foreign import ccall unsafe "BinaryenSIMDShuffleId" simdShuffleId :: ExpressionId
+foreign import ccall unsafe "BinaryenSIMDTernaryId" simdTernaryId :: ExpressionId
+foreign import ccall unsafe "BinaryenSIMDShiftId" simdShiftId :: ExpressionId
+foreign import ccall unsafe "BinaryenSIMDLoadId" simdLoadId :: ExpressionId
+foreign import ccall unsafe "BinaryenMemoryInitId" memoryInitId :: ExpressionId
+foreign import ccall unsafe "BinaryenDataDropId" dataDropId :: ExpressionId
+foreign import ccall unsafe "BinaryenMemoryCopyId" memoryCopyId :: ExpressionId
+foreign import ccall unsafe "BinaryenMemoryFillId" memoryFillId :: ExpressionId
+foreign import ccall unsafe "BinaryenRefNullId" refNullId :: ExpressionId
+foreign import ccall unsafe "BinaryenRefIsNullId" refIsNullId :: ExpressionId
+foreign import ccall unsafe "BinaryenRefFuncId" refFuncId :: ExpressionId
+foreign import ccall unsafe "BinaryenTryId" tryId :: ExpressionId
+foreign import ccall unsafe "BinaryenThrowId" throwId :: ExpressionId
+foreign import ccall unsafe "BinaryenRethrowId" rethrowId :: ExpressionId
+foreign import ccall unsafe "BinaryenBrOnExnId" brOnExnId :: ExpressionId
+foreign import ccall unsafe "BinaryenPushId" pushId :: ExpressionId
+foreign import ccall unsafe "BinaryenPopId" popId :: ExpressionId
diff --git a/src/Binaryen/ExternalKind.hs b/src/Binaryen/ExternalKind.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/ExternalKind.hs
@@ -0,0 +1,22 @@
+-- | External kinds.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.ExternalKind where
+
+import Data.Word (Word32)
+import Foreign (Storable)
+
+newtype ExternalKind = ExternalKind Word32
+  deriving (Eq, Show, Storable)
+
+foreign import ccall unsafe "BinaryenExternalFunction" externalFunction :: ExternalKind
+foreign import ccall unsafe "BinaryenExternalTable" externalTable :: ExternalKind
+foreign import ccall unsafe "BinaryenExternalMemory" externalMemory :: ExternalKind
+foreign import ccall unsafe "BinaryenExternalGlobal" externalGlobal :: ExternalKind
+foreign import ccall unsafe "BinaryenExternalEvent" externalEvent :: ExternalKind
diff --git a/src/Binaryen/Features.hs b/src/Binaryen/Features.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/Features.hs
@@ -0,0 +1,29 @@
+-- | WebAssembly features.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.Features where
+
+import Data.Bits (Bits)
+import Data.Word (Word32)
+import Foreign (Storable)
+
+newtype Features = Features Word32
+  deriving (Bits, Eq, Show, Storable)
+
+foreign import ccall unsafe "BinaryenFeatureMVP" mvp :: Features
+foreign import ccall unsafe "BinaryenFeatureAtomics" atomics :: Features
+foreign import ccall unsafe "BinaryenFeatureBulkMemory" bulkMemory :: Features
+foreign import ccall unsafe "BinaryenFeatureMutableGlobals" mutableGlobals :: Features
+foreign import ccall unsafe "BinaryenFeatureNontrappingFPToInt" nontrappingFPToInt :: Features
+foreign import ccall unsafe "BinaryenFeatureSignExt" signExt :: Features
+foreign import ccall unsafe "BinaryenFeatureSIMD128" simd128 :: Features
+foreign import ccall unsafe "BinaryenFeatureExceptionHandling" exceptionHandling :: Features
+foreign import ccall unsafe "BinaryenFeatureTailCall" tailCall :: Features
+foreign import ccall unsafe "BinaryenFeatureReferenceTypes" referenceTypes :: Features
+foreign import ccall unsafe "BinaryenFeatureAll" all :: Features
diff --git a/src/Binaryen/Function.hs b/src/Binaryen/Function.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/Function.hs
@@ -0,0 +1,73 @@
+-- | Functions.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.Function where
+
+import Binaryen.Expression
+import Binaryen.Index
+import {-# SOURCE #-} Binaryen.Module
+import Binaryen.Type
+import Foreign (Ptr, Storable)
+import Foreign.C (CChar(..))
+
+newtype Function = Function (Ptr Function)
+  deriving (Eq, Show, Storable)
+
+foreign import ccall unsafe "BinaryenFunctionGetName"
+  getName ::
+    Function -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenFunctionGetParams"
+  getParams ::
+    Function -> IO Type
+
+foreign import ccall unsafe "BinaryenFunctionGetResults"
+  getResults ::
+    Function -> IO Type
+
+foreign import ccall unsafe "BinaryenFunctionGetNumVars"
+  getNumVars ::
+    Function -> IO Index
+
+foreign import ccall unsafe "BinaryenFunctionGetVar"
+  getVar ::
+    Function -> Index -> IO Type
+
+foreign import ccall unsafe "BinaryenFunctionGetBody"
+  getBody ::
+    Function -> IO Expression
+
+foreign import ccall unsafe "BinaryenFunctionSetDebugLocation"
+  setDebugLocation ::
+    Function ->
+    Expression ->
+    Index ->
+    Index ->
+    Index ->
+    IO ()
+
+foreign import ccall unsafe "BinaryenFunctionImportGetModule"
+  importGetModule ::
+    Function -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenFunctionImportGetBase"
+  importGetBase ::
+    Function -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenFunctionOptimize"
+  optimize ::
+    Function -> Module -> IO ()
+
+foreign import ccall unsafe "BinaryenFunctionRunPasses"
+  runPasses ::
+    Function ->
+    Module ->
+    Ptr (Ptr CChar) ->
+    Index ->
+    IO ()
diff --git a/src/Binaryen/Global.hs b/src/Binaryen/Global.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/Global.hs
@@ -0,0 +1,42 @@
+-- | Globals.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.Global where
+
+import Binaryen.Type
+import Binaryen.Expression
+import Foreign (Ptr, Storable)
+import Foreign.C (CChar(..), CInt(..))
+
+newtype Global = Global (Ptr Global)
+  deriving (Eq, Show, Storable)
+
+foreign import ccall unsafe "BinaryenGlobalGetName"
+  getName ::
+    Global -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenGlobalGetType"
+  getType ::
+    Global -> IO Type
+
+foreign import ccall unsafe "BinaryenGlobalIsMutable"
+  isMutable ::
+    Global -> IO CInt
+
+foreign import ccall unsafe "BinaryenGlobalGetInitExpr"
+  getInitExpr ::
+    Global -> IO Expression
+
+foreign import ccall unsafe "BinaryenGlobalImportGetModule"
+  importGetModule ::
+    Global -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenGlobalImportGetBase"
+  globalImportGetBase ::
+    Global -> IO (Ptr CChar)
diff --git a/src/Binaryen/Index.hs b/src/Binaryen/Index.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/Index.hs
@@ -0,0 +1,17 @@
+-- | The Binaryen index type.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE DerivingStrategies #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.Index where
+
+import Data.Word (Word32)
+import Foreign (Storable)
+
+newtype Index = Index Word32
+  deriving newtype (Eq, Num, Show, Storable)
diff --git a/src/Binaryen/Module.hs b/src/Binaryen/Module.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/Module.hs
@@ -0,0 +1,327 @@
+-- | Modules.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.Module where
+
+import Binaryen.Index
+import Binaryen.Event
+import Binaryen.Export
+import Binaryen.Expression
+import Binaryen.Features
+import Binaryen.Function
+import Binaryen.Global
+import Binaryen.Type
+import Data.Int (Int8)
+import Data.Word (Word8, Word32)
+import Foreign (Ptr, Storable)
+import Foreign.C (CChar(..), CInt(..), CSize(..))
+
+newtype Module = Module (Ptr Module)
+  deriving (Eq, Show, Storable)
+
+foreign import ccall unsafe "BinaryenModuleCreate"
+  create ::
+    IO Module
+
+foreign import ccall unsafe "BinaryenModuleDispose"
+  dispose ::
+    Module -> IO ()
+
+foreign import ccall unsafe "BinaryenAddFunction"
+  addFunction ::
+    Module ->
+    Ptr CChar ->
+    Type ->
+    Type ->
+    Ptr Type ->
+    Index ->
+    Expression ->
+    IO Function
+
+foreign import ccall unsafe "BinaryenGetFunction"
+  getFunction ::
+    Module -> Ptr CChar -> IO Function
+
+foreign import ccall unsafe "BinaryenRemoveFunction"
+  removeFunction ::
+    Module -> Ptr CChar -> IO ()
+
+foreign import ccall unsafe "BinaryenGetNumFunctions"
+  getNumFunctions ::
+    Module -> IO Word32
+
+foreign import ccall unsafe "BinaryenGetFunctionByIndex"
+  getFunctionByIndex ::
+    Module -> Index -> IO Function
+
+foreign import ccall unsafe "BinaryenAddFunctionImport"
+  addFunctionImport ::
+    Module ->
+    Ptr CChar ->
+    Ptr CChar ->
+    Ptr CChar ->
+    Type ->
+    Type ->
+    IO ()
+
+foreign import ccall unsafe "BinaryenAddTableImport"
+  addTableImport ::
+    Module ->
+    Ptr CChar ->
+    Ptr CChar ->
+    Ptr CChar ->
+    IO ()
+
+foreign import ccall unsafe "BinaryenAddMemoryImport"
+  addMemoryImport ::
+    Module ->
+    Ptr CChar ->
+    Ptr CChar ->
+    Ptr CChar ->
+    Word8 ->
+    IO ()
+
+foreign import ccall unsafe "BinaryenAddGlobalImport"
+  addGlobalImport ::
+    Module ->
+    Ptr CChar ->
+    Ptr CChar ->
+    Ptr CChar ->
+    Type ->
+    CInt ->
+    IO ()
+
+foreign import ccall unsafe "BinaryenAddEventImport"
+  addEventImport ::
+    Module ->
+    Ptr CChar ->
+    Ptr CChar ->
+    Ptr CChar ->
+    Word32 ->
+    Type ->
+    Type ->
+    IO ()
+
+foreign import ccall unsafe "BinaryenAddFunctionExport"
+  addFunctionExport ::
+    Module -> Ptr CChar -> Ptr CChar -> IO Export
+
+foreign import ccall unsafe "BinaryenAddTableExport"
+  addTableExport ::
+    Module -> Ptr CChar -> Ptr CChar -> IO Export
+
+foreign import ccall unsafe "BinaryenAddMemoryExport"
+  addMemoryExport ::
+    Module -> Ptr CChar -> Ptr CChar -> IO Export
+
+foreign import ccall unsafe "BinaryenAddGlobalExport"
+  addGlobalExport ::
+    Module -> Ptr CChar -> Ptr CChar -> IO Export
+
+foreign import ccall unsafe "BinaryenAddEventExport"
+  addEventExport ::
+    Module -> Ptr CChar -> Ptr CChar -> IO Export
+
+foreign import ccall unsafe "BinaryenRemoveExport"
+  removeExport ::
+    Module -> Ptr CChar -> IO ()
+
+foreign import ccall unsafe "BinaryenAddEvent"
+  addEvent ::
+    Module ->
+    Ptr CChar ->
+    Word32 ->
+    Type ->
+    Type ->
+    IO Event
+
+foreign import ccall unsafe "BinaryenGetEvent"
+  getEvent ::
+    Module -> Ptr CChar -> IO Event
+
+foreign import ccall unsafe "BinaryenRemoveEvent"
+  removeEvent ::
+    Module -> Ptr CChar -> IO ()
+
+foreign import ccall unsafe "BinaryenSetFunctionTable"
+  setFunctionTable ::
+    Module ->
+    Index ->
+    Index ->
+    Ptr (Ptr CChar) ->
+    Index ->
+    Expression ->
+    IO ()
+
+foreign import ccall unsafe "BinaryenIsFunctionTableImported"
+  isFunctionTableImported ::
+    Module -> IO CInt
+
+foreign import ccall unsafe "BinaryenGetNumFunctionTableSegments"
+  getNumFunctionTableSegments ::
+    Module -> IO Index
+
+foreign import ccall unsafe "BinaryenGetFunctionTableSegmentOffset"
+  getFunctionTableSegmentOffset ::
+    Module -> Index -> IO Expression
+
+foreign import ccall unsafe "BinaryenGetFunctionTableSegmentLength"
+  getFunctionTableSegmentLength ::
+    Module -> Index -> IO Index
+
+foreign import ccall unsafe "BinaryenGetFunctionTableSegmentData"
+  getFunctionTableSegmentData ::
+    Module ->
+    Index ->
+    Index ->
+    IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenSetMemory"
+  setMemory ::
+    Module ->
+    Index ->
+    Index ->
+    Ptr CChar ->
+    Ptr (Ptr CChar) ->
+    Ptr Int8 ->
+    Ptr Expression ->
+    Ptr Index ->
+    Index ->
+    Word8 ->
+    IO ()
+
+foreign import ccall unsafe "BinaryenGetNumMemorySegments"
+  getNumMemorySegments ::
+    Module -> IO Word32
+
+foreign import ccall unsafe "BinaryenGetMemorySegmentByteOffset"
+  getMemorySegmentByteOffset ::
+    Module -> Index -> IO Word32
+
+foreign import ccall unsafe "BinaryenGetMemorySegmentByteLength"
+  getMemorySegmentByteLength ::
+    Module -> Index -> IO CSize
+
+foreign import ccall unsafe "BinaryenGetMemorySegmentPassive"
+  getMemorySegmentPassive ::
+    Module -> Index -> IO CInt
+
+foreign import ccall unsafe "BinaryenCopyMemorySegmentData"
+  copyMemorySegmentData ::
+    Module -> Index -> Ptr CChar -> IO ()
+
+foreign import ccall unsafe "BinaryenSetStart"
+  setStart ::
+    Module -> Function -> IO ()
+
+foreign import ccall unsafe "BinaryenModuleGetFeatures"
+  getFeatures ::
+    Module -> IO Features
+
+foreign import ccall unsafe "BinaryenModuleSetFeatures"
+  setFeatures ::
+    Module -> Features -> IO ()
+
+foreign import ccall unsafe "BinaryenModuleParse"
+  parse ::
+    Ptr CChar -> IO Module
+
+foreign import ccall unsafe "BinaryenModulePrint"
+  print ::
+    Module -> IO ()
+
+foreign import ccall unsafe "BinaryenModulePrintAsmjs"
+  printAsmjs ::
+    Module -> IO ()
+
+foreign import ccall unsafe "BinaryenModuleValidate"
+  validate ::
+    Module -> IO CInt
+
+foreign import ccall unsafe "BinaryenModuleOptimize"
+  optimize ::
+    Module -> IO ()
+
+foreign import ccall unsafe "BinaryenAddCustomSection"
+  addCustomSection ::
+    Module ->
+    Ptr CChar ->
+    Ptr CChar ->
+    Index ->
+    IO ()
+
+foreign import ccall unsafe "BinaryenGetNumExports"
+  getNumExports ::
+    Module -> IO Word32
+
+foreign import ccall unsafe "BinaryenGetExportByIndex"
+  getExportByIndex ::
+    Module -> Index -> IO Export
+
+foreign import ccall unsafe "BinaryenModuleRunPasses"
+  runPasses ::
+    Module -> Ptr (Ptr CChar) -> Index -> IO ()
+
+foreign import ccall unsafe "BinaryenModuleAutoDrop"
+  autoDrop ::
+    Module -> IO ()
+
+foreign import ccall unsafe "BinaryenModuleWrite"
+  write ::
+    Module -> Ptr CChar -> CSize -> IO CSize
+
+foreign import ccall unsafe "BinaryenModuleWriteText"
+  writeText ::
+    Module -> Ptr CChar -> CSize -> IO CSize
+
+foreign import ccall unsafe "BinaryenModuleAllocateAndWriteMut"
+  allocateAndWriteMut ::
+    Module ->
+    Ptr CChar ->
+    Ptr (Ptr ()) ->
+    Ptr CSize ->
+    Ptr (Ptr CChar) ->
+    IO ()
+
+foreign import ccall unsafe "BinaryenModuleAllocateAndWriteText"
+  allocateAndWriteText ::
+    Module -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenModuleRead"
+  read ::
+    Ptr CChar -> CSize -> IO Module
+
+foreign import ccall unsafe "BinaryenModuleInterpret"
+  interpret ::
+    Module -> IO ()
+
+foreign import ccall unsafe "BinaryenModuleAddDebugInfoFileName"
+  addDebugInfoFileName ::
+    Module -> Ptr CChar -> IO Index
+
+foreign import ccall unsafe "BinaryenModuleGetDebugInfoFileName"
+  getDebugInfoFileName ::
+    Module -> Index -> IO (Ptr CChar)
+
+foreign import ccall unsafe "BinaryenAddGlobal"
+  addGlobal ::
+    Module ->
+    Ptr CChar ->
+    Type ->
+    Int8 ->
+    Expression ->
+    IO Global
+
+foreign import ccall unsafe "BinaryenGetGlobal"
+  getGlobal ::
+    Module -> Ptr CChar -> IO Global
+
+foreign import ccall unsafe "BinaryenRemoveGlobal"
+  removeGlobal ::
+    Module -> Ptr CChar -> IO ()
diff --git a/src/Binaryen/Module.hs-boot b/src/Binaryen/Module.hs-boot
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/Module.hs-boot
@@ -0,0 +1,5 @@
+module Binaryen.Module where
+
+import Foreign.Ptr (Ptr)
+
+newtype Module = Module (Ptr Module)
diff --git a/src/Binaryen/Op.hs b/src/Binaryen/Op.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/Op.hs
@@ -0,0 +1,340 @@
+-- | Operators.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.Op where
+
+import Data.Int (Int32)
+import Foreign (Storable)
+
+newtype Op = Op Int32
+  deriving (Eq, Show, Storable)
+
+foreign import ccall unsafe "BinaryenClzInt32" clzInt32 :: Op
+foreign import ccall unsafe "BinaryenCtzInt32" ctzInt32 :: Op
+foreign import ccall unsafe "BinaryenPopcntInt32" popcntInt32 :: Op
+foreign import ccall unsafe "BinaryenNegFloat32" negFloat32 :: Op
+foreign import ccall unsafe "BinaryenAbsFloat32" absFloat32 :: Op
+foreign import ccall unsafe "BinaryenCeilFloat32" ceilFloat32 :: Op
+foreign import ccall unsafe "BinaryenFloorFloat32" floorFloat32 :: Op
+foreign import ccall unsafe "BinaryenTruncFloat32" truncFloat32 :: Op
+foreign import ccall unsafe "BinaryenNearestFloat32" nearestFloat32 :: Op
+foreign import ccall unsafe "BinaryenSqrtFloat32" sqrtFloat32 :: Op
+foreign import ccall unsafe "BinaryenEqZInt32" eqZInt32 :: Op
+foreign import ccall unsafe "BinaryenClzInt64" clzInt64 :: Op
+foreign import ccall unsafe "BinaryenCtzInt64" ctzInt64 :: Op
+foreign import ccall unsafe "BinaryenPopcntInt64" popcntInt64 :: Op
+foreign import ccall unsafe "BinaryenNegFloat64" negFloat64 :: Op
+foreign import ccall unsafe "BinaryenAbsFloat64" absFloat64 :: Op
+foreign import ccall unsafe "BinaryenCeilFloat64" ceilFloat64 :: Op
+foreign import ccall unsafe "BinaryenFloorFloat64" floorFloat64 :: Op
+foreign import ccall unsafe "BinaryenTruncFloat64" truncFloat64 :: Op
+foreign import ccall unsafe "BinaryenNearestFloat64" nearestFloat64 :: Op
+foreign import ccall unsafe "BinaryenSqrtFloat64" sqrtFloat64 :: Op
+foreign import ccall unsafe "BinaryenEqZInt64" eqZInt64 :: Op
+foreign import ccall unsafe "BinaryenExtendSInt32" extendSInt32 :: Op
+foreign import ccall unsafe "BinaryenExtendUInt32" extendUInt32 :: Op
+foreign import ccall unsafe "BinaryenWrapInt64" wrapInt64 :: Op
+foreign import ccall unsafe "BinaryenTruncSFloat32ToInt32" truncSFloat32ToInt32 :: Op
+foreign import ccall unsafe "BinaryenTruncSFloat32ToInt64" truncSFloat32ToInt64 :: Op
+foreign import ccall unsafe "BinaryenTruncUFloat32ToInt32" truncUFloat32ToInt32 :: Op
+foreign import ccall unsafe "BinaryenTruncUFloat32ToInt64" truncUFloat32ToInt64 :: Op
+foreign import ccall unsafe "BinaryenTruncSFloat64ToInt32" truncSFloat64ToInt32 :: Op
+foreign import ccall unsafe "BinaryenTruncSFloat64ToInt64" truncSFloat64ToInt64 :: Op
+foreign import ccall unsafe "BinaryenTruncUFloat64ToInt32" truncUFloat64ToInt32 :: Op
+foreign import ccall unsafe "BinaryenTruncUFloat64ToInt64" truncUFloat64ToInt64 :: Op
+foreign import ccall unsafe "BinaryenReinterpretFloat32" reinterpretFloat32 :: Op
+foreign import ccall unsafe "BinaryenReinterpretFloat64" reinterpretFloat64 :: Op
+foreign import ccall unsafe "BinaryenConvertSInt32ToFloat32" convertSInt32ToFloat32 :: Op
+foreign import ccall unsafe "BinaryenConvertSInt32ToFloat64" convertSInt32ToFloat64 :: Op
+foreign import ccall unsafe "BinaryenConvertUInt32ToFloat32" convertUInt32ToFloat32 :: Op
+foreign import ccall unsafe "BinaryenConvertUInt32ToFloat64" convertUInt32ToFloat64 :: Op
+foreign import ccall unsafe "BinaryenConvertSInt64ToFloat32" convertSInt64ToFloat32 :: Op
+foreign import ccall unsafe "BinaryenConvertSInt64ToFloat64" convertSInt64ToFloat64 :: Op
+foreign import ccall unsafe "BinaryenConvertUInt64ToFloat32" convertUInt64ToFloat32 :: Op
+foreign import ccall unsafe "BinaryenConvertUInt64ToFloat64" convertUInt64ToFloat64 :: Op
+foreign import ccall unsafe "BinaryenPromoteFloat32" promoteFloat32 :: Op
+foreign import ccall unsafe "BinaryenDemoteFloat64" demoteFloat64 :: Op
+foreign import ccall unsafe "BinaryenReinterpretInt32" reinterpretInt32 :: Op
+foreign import ccall unsafe "BinaryenReinterpretInt64" reinterpretInt64 :: Op
+foreign import ccall unsafe "BinaryenExtendS8Int32" extendS8Int32 :: Op
+foreign import ccall unsafe "BinaryenExtendS16Int32" extendS16Int32 :: Op
+foreign import ccall unsafe "BinaryenExtendS8Int64" extendS8Int64 :: Op
+foreign import ccall unsafe "BinaryenExtendS16Int64" extendS16Int64 :: Op
+foreign import ccall unsafe "BinaryenExtendS32Int64" extendS32Int64 :: Op
+foreign import ccall unsafe "BinaryenAddInt32" addInt32 :: Op
+foreign import ccall unsafe "BinaryenSubInt32" subInt32 :: Op
+foreign import ccall unsafe "BinaryenMulInt32" mulInt32 :: Op
+foreign import ccall unsafe "BinaryenDivSInt32" divSInt32 :: Op
+foreign import ccall unsafe "BinaryenDivUInt32" divUInt32 :: Op
+foreign import ccall unsafe "BinaryenRemSInt32" remSInt32 :: Op
+foreign import ccall unsafe "BinaryenRemUInt32" remUInt32 :: Op
+foreign import ccall unsafe "BinaryenAndInt32" andInt32 :: Op
+foreign import ccall unsafe "BinaryenOrInt32" orInt32 :: Op
+foreign import ccall unsafe "BinaryenXorInt32" xorInt32 :: Op
+foreign import ccall unsafe "BinaryenShlInt32" shlInt32 :: Op
+foreign import ccall unsafe "BinaryenShrUInt32" shrUInt32 :: Op
+foreign import ccall unsafe "BinaryenShrSInt32" shrSInt32 :: Op
+foreign import ccall unsafe "BinaryenRotLInt32" rotLInt32 :: Op
+foreign import ccall unsafe "BinaryenRotRInt32" rotRInt32 :: Op
+foreign import ccall unsafe "BinaryenEqInt32" eqInt32 :: Op
+foreign import ccall unsafe "BinaryenNeInt32" neInt32 :: Op
+foreign import ccall unsafe "BinaryenLtSInt32" ltSInt32 :: Op
+foreign import ccall unsafe "BinaryenLtUInt32" ltUInt32 :: Op
+foreign import ccall unsafe "BinaryenLeSInt32" leSInt32 :: Op
+foreign import ccall unsafe "BinaryenLeUInt32" leUInt32 :: Op
+foreign import ccall unsafe "BinaryenGtSInt32" gtSInt32 :: Op
+foreign import ccall unsafe "BinaryenGtUInt32" gtUInt32 :: Op
+foreign import ccall unsafe "BinaryenGeSInt32" geSInt32 :: Op
+foreign import ccall unsafe "BinaryenGeUInt32" geUInt32 :: Op
+foreign import ccall unsafe "BinaryenAddInt64" addInt64 :: Op
+foreign import ccall unsafe "BinaryenSubInt64" subInt64 :: Op
+foreign import ccall unsafe "BinaryenMulInt64" mulInt64 :: Op
+foreign import ccall unsafe "BinaryenDivSInt64" divSInt64 :: Op
+foreign import ccall unsafe "BinaryenDivUInt64" divUInt64 :: Op
+foreign import ccall unsafe "BinaryenRemSInt64" remSInt64 :: Op
+foreign import ccall unsafe "BinaryenRemUInt64" remUInt64 :: Op
+foreign import ccall unsafe "BinaryenAndInt64" andInt64 :: Op
+foreign import ccall unsafe "BinaryenOrInt64" orInt64 :: Op
+foreign import ccall unsafe "BinaryenXorInt64" xorInt64 :: Op
+foreign import ccall unsafe "BinaryenShlInt64" shlInt64 :: Op
+foreign import ccall unsafe "BinaryenShrUInt64" shrUInt64 :: Op
+foreign import ccall unsafe "BinaryenShrSInt64" shrSInt64 :: Op
+foreign import ccall unsafe "BinaryenRotLInt64" rotLInt64 :: Op
+foreign import ccall unsafe "BinaryenRotRInt64" rotRInt64 :: Op
+foreign import ccall unsafe "BinaryenEqInt64" eqInt64 :: Op
+foreign import ccall unsafe "BinaryenNeInt64" neInt64 :: Op
+foreign import ccall unsafe "BinaryenLtSInt64" ltSInt64 :: Op
+foreign import ccall unsafe "BinaryenLtUInt64" ltUInt64 :: Op
+foreign import ccall unsafe "BinaryenLeSInt64" leSInt64 :: Op
+foreign import ccall unsafe "BinaryenLeUInt64" leUInt64 :: Op
+foreign import ccall unsafe "BinaryenGtSInt64" gtSInt64 :: Op
+foreign import ccall unsafe "BinaryenGtUInt64" gtUInt64 :: Op
+foreign import ccall unsafe "BinaryenGeSInt64" geSInt64 :: Op
+foreign import ccall unsafe "BinaryenGeUInt64" geUInt64 :: Op
+foreign import ccall unsafe "BinaryenAddFloat32" addFloat32 :: Op
+foreign import ccall unsafe "BinaryenSubFloat32" subFloat32 :: Op
+foreign import ccall unsafe "BinaryenMulFloat32" mulFloat32 :: Op
+foreign import ccall unsafe "BinaryenDivFloat32" divFloat32 :: Op
+foreign import ccall unsafe "BinaryenCopySignFloat32" copySignFloat32 :: Op
+foreign import ccall unsafe "BinaryenMinFloat32" minFloat32 :: Op
+foreign import ccall unsafe "BinaryenMaxFloat32" maxFloat32 :: Op
+foreign import ccall unsafe "BinaryenEqFloat32" eqFloat32 :: Op
+foreign import ccall unsafe "BinaryenNeFloat32" neFloat32 :: Op
+foreign import ccall unsafe "BinaryenLtFloat32" ltFloat32 :: Op
+foreign import ccall unsafe "BinaryenLeFloat32" leFloat32 :: Op
+foreign import ccall unsafe "BinaryenGtFloat32" gtFloat32 :: Op
+foreign import ccall unsafe "BinaryenGeFloat32" geFloat32 :: Op
+foreign import ccall unsafe "BinaryenAddFloat64" addFloat64 :: Op
+foreign import ccall unsafe "BinaryenSubFloat64" subFloat64 :: Op
+foreign import ccall unsafe "BinaryenMulFloat64" mulFloat64 :: Op
+foreign import ccall unsafe "BinaryenDivFloat64" divFloat64 :: Op
+foreign import ccall unsafe "BinaryenCopySignFloat64" copySignFloat64 :: Op
+foreign import ccall unsafe "BinaryenMinFloat64" minFloat64 :: Op
+foreign import ccall unsafe "BinaryenMaxFloat64" maxFloat64 :: Op
+foreign import ccall unsafe "BinaryenEqFloat64" eqFloat64 :: Op
+foreign import ccall unsafe "BinaryenNeFloat64" neFloat64 :: Op
+foreign import ccall unsafe "BinaryenLtFloat64" ltFloat64 :: Op
+foreign import ccall unsafe "BinaryenLeFloat64" leFloat64 :: Op
+foreign import ccall unsafe "BinaryenGtFloat64" gtFloat64 :: Op
+foreign import ccall unsafe "BinaryenGeFloat64" geFloat64 :: Op
+foreign import ccall unsafe "BinaryenMemorySize" memorySize :: Op
+foreign import ccall unsafe "BinaryenMemoryGrow" memoryGrow :: Op
+foreign import ccall unsafe "BinaryenAtomicRMWAdd" atomicRMWAdd :: Op
+foreign import ccall unsafe "BinaryenAtomicRMWSub" atomicRMWSub :: Op
+foreign import ccall unsafe "BinaryenAtomicRMWAnd" atomicRMWAnd :: Op
+foreign import ccall unsafe "BinaryenAtomicRMWOr" atomicRMWOr :: Op
+foreign import ccall unsafe "BinaryenAtomicRMWXor" atomicRMWXor :: Op
+foreign import ccall unsafe "BinaryenAtomicRMWXchg" atomicRMWXchg :: Op
+foreign import ccall unsafe "BinaryenTruncSatSFloat32ToInt32" truncSatSFloat32ToInt32 :: Op
+foreign import ccall unsafe "BinaryenTruncSatSFloat32ToInt64" truncSatSFloat32ToInt64 :: Op
+foreign import ccall unsafe "BinaryenTruncSatUFloat32ToInt32" truncSatUFloat32ToInt32 :: Op
+foreign import ccall unsafe "BinaryenTruncSatUFloat32ToInt64" truncSatUFloat32ToInt64 :: Op
+foreign import ccall unsafe "BinaryenTruncSatSFloat64ToInt32" truncSatSFloat64ToInt32 :: Op
+foreign import ccall unsafe "BinaryenTruncSatSFloat64ToInt64" truncSatSFloat64ToInt64 :: Op
+foreign import ccall unsafe "BinaryenTruncSatUFloat64ToInt32" truncSatUFloat64ToInt32 :: Op
+foreign import ccall unsafe "BinaryenTruncSatUFloat64ToInt64" truncSatUFloat64ToInt64 :: Op
+foreign import ccall unsafe "BinaryenSplatVecI8x16" splatVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenExtractLaneSVecI8x16" extractLaneSVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenExtractLaneUVecI8x16" extractLaneUVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenReplaceLaneVecI8x16" replaceLaneVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenSplatVecI16x8" splatVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenExtractLaneSVecI16x8" extractLaneSVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenExtractLaneUVecI16x8" extractLaneUVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenReplaceLaneVecI16x8" replaceLaneVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenSplatVecI32x4" splatVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenExtractLaneVecI32x4" extractLaneVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenReplaceLaneVecI32x4" replaceLaneVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenSplatVecI64x2" splatVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenExtractLaneVecI64x2" extractLaneVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenReplaceLaneVecI64x2" replaceLaneVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenSplatVecF32x4" splatVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenExtractLaneVecF32x4" extractLaneVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenReplaceLaneVecF32x4" replaceLaneVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenSplatVecF64x2" splatVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenExtractLaneVecF64x2" extractLaneVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenReplaceLaneVecF64x2" replaceLaneVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenEqVecI8x16" eqVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenNeVecI8x16" neVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenLtSVecI8x16" ltSVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenLtUVecI8x16" ltUVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenGtSVecI8x16" gtSVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenGtUVecI8x16" gtUVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenLeSVecI8x16" leSVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenLeUVecI8x16" leUVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenGeSVecI8x16" geSVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenGeUVecI8x16" geUVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenEqVecI16x8" eqVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenNeVecI16x8" neVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenLtSVecI16x8" ltSVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenLtUVecI16x8" ltUVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenGtSVecI16x8" gtSVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenGtUVecI16x8" gtUVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenLeSVecI16x8" leSVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenLeUVecI16x8" leUVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenGeSVecI16x8" geSVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenGeUVecI16x8" geUVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenEqVecI32x4" eqVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenNeVecI32x4" neVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenLtSVecI32x4" ltSVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenLtUVecI32x4" ltUVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenGtSVecI32x4" gtSVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenGtUVecI32x4" gtUVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenLeSVecI32x4" leSVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenLeUVecI32x4" leUVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenGeSVecI32x4" geSVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenGeUVecI32x4" geUVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenEqVecF32x4" eqVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenNeVecF32x4" neVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenLtVecF32x4" ltVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenGtVecF32x4" gtVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenLeVecF32x4" leVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenGeVecF32x4" geVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenEqVecF64x2" eqVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenNeVecF64x2" neVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenLtVecF64x2" ltVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenGtVecF64x2" gtVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenLeVecF64x2" leVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenGeVecF64x2" geVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenNotVec128" notVec128 :: Op
+foreign import ccall unsafe "BinaryenAndVec128" andVec128 :: Op
+foreign import ccall unsafe "BinaryenOrVec128" orVec128 :: Op
+foreign import ccall unsafe "BinaryenXorVec128" xorVec128 :: Op
+foreign import ccall unsafe "BinaryenAndNotVec128" andNotVec128 :: Op
+foreign import ccall unsafe "BinaryenBitselectVec128" bitselectVec128 :: Op
+foreign import ccall unsafe "BinaryenNegVecI8x16" negVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenAnyTrueVecI8x16" anyTrueVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenAllTrueVecI8x16" allTrueVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenShlVecI8x16" shlVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenShrSVecI8x16" shrSVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenShrUVecI8x16" shrUVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenAddVecI8x16" addVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenAddSatSVecI8x16" addSatSVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenAddSatUVecI8x16" addSatUVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenSubVecI8x16" subVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenSubSatSVecI8x16" subSatSVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenSubSatUVecI8x16" subSatUVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenMulVecI8x16" mulVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenMinSVecI8x16" minSVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenMinUVecI8x16" minUVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenMaxSVecI8x16" maxSVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenMaxUVecI8x16" maxUVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenAvgrUVecI8x16" avgrUVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenNegVecI16x8" negVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenAnyTrueVecI16x8" anyTrueVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenAllTrueVecI16x8" allTrueVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenShlVecI16x8" shlVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenShrSVecI16x8" shrSVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenShrUVecI16x8" shrUVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenAddVecI16x8" addVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenAddSatSVecI16x8" addSatSVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenAddSatUVecI16x8" addSatUVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenSubVecI16x8" subVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenSubSatSVecI16x8" subSatSVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenSubSatUVecI16x8" subSatUVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenMulVecI16x8" mulVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenMinSVecI16x8" minSVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenMinUVecI16x8" minUVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenMaxSVecI16x8" maxSVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenMaxUVecI16x8" maxUVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenAvgrUVecI16x8" avgrUVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenNegVecI32x4" negVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenAnyTrueVecI32x4" anyTrueVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenAllTrueVecI32x4" allTrueVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenShlVecI32x4" shlVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenShrSVecI32x4" shrSVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenShrUVecI32x4" shrUVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenAddVecI32x4" addVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenSubVecI32x4" subVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenMulVecI32x4" mulVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenMinSVecI32x4" minSVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenMinUVecI32x4" minUVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenMaxSVecI32x4" maxSVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenMaxUVecI32x4" maxUVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenDotSVecI16x8ToVecI32x4" dotSVecI16x8ToVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenNegVecI64x2" negVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenAnyTrueVecI64x2" anyTrueVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenAllTrueVecI64x2" allTrueVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenShlVecI64x2" shlVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenShrSVecI64x2" shrSVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenShrUVecI64x2" shrUVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenAddVecI64x2" addVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenSubVecI64x2" subVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenAbsVecF32x4" absVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenNegVecF32x4" negVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenSqrtVecF32x4" sqrtVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenQFMAVecF32x4" qFMAVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenQFMSVecF32x4" qFMSVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenAddVecF32x4" addVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenSubVecF32x4" subVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenMulVecF32x4" mulVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenDivVecF32x4" divVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenMinVecF32x4" minVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenMaxVecF32x4" maxVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenAbsVecF64x2" absVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenNegVecF64x2" negVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenSqrtVecF64x2" sqrtVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenQFMAVecF64x2" qFMAVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenQFMSVecF64x2" qFMSVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenAddVecF64x2" addVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenSubVecF64x2" subVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenMulVecF64x2" mulVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenDivVecF64x2" divVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenMinVecF64x2" minVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenMaxVecF64x2" maxVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenTruncSatSVecF32x4ToVecI32x4" truncSatSVecF32x4ToVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenTruncSatUVecF32x4ToVecI32x4" truncSatUVecF32x4ToVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenTruncSatSVecF64x2ToVecI64x2" truncSatSVecF64x2ToVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenTruncSatUVecF64x2ToVecI64x2" truncSatUVecF64x2ToVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenConvertSVecI32x4ToVecF32x4" convertSVecI32x4ToVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenConvertUVecI32x4ToVecF32x4" convertUVecI32x4ToVecF32x4 :: Op
+foreign import ccall unsafe "BinaryenConvertSVecI64x2ToVecF64x2" convertSVecI64x2ToVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenConvertUVecI64x2ToVecF64x2" convertUVecI64x2ToVecF64x2 :: Op
+foreign import ccall unsafe "BinaryenLoadSplatVec8x16" loadSplatVec8x16 :: Op
+foreign import ccall unsafe "BinaryenLoadSplatVec16x8" loadSplatVec16x8 :: Op
+foreign import ccall unsafe "BinaryenLoadSplatVec32x4" loadSplatVec32x4 :: Op
+foreign import ccall unsafe "BinaryenLoadSplatVec64x2" loadSplatVec64x2 :: Op
+foreign import ccall unsafe "BinaryenLoadExtSVec8x8ToVecI16x8" loadExtSVec8x8ToVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenLoadExtUVec8x8ToVecI16x8" loadExtUVec8x8ToVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenLoadExtSVec16x4ToVecI32x4" loadExtSVec16x4ToVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenLoadExtUVec16x4ToVecI32x4" loadExtUVec16x4ToVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenLoadExtSVec32x2ToVecI64x2" loadExtSVec32x2ToVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenLoadExtUVec32x2ToVecI64x2" loadExtUVec32x2ToVecI64x2 :: Op
+foreign import ccall unsafe "BinaryenNarrowSVecI16x8ToVecI8x16" narrowSVecI16x8ToVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenNarrowUVecI16x8ToVecI8x16" narrowUVecI16x8ToVecI8x16 :: Op
+foreign import ccall unsafe "BinaryenNarrowSVecI32x4ToVecI16x8" narrowSVecI32x4ToVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenNarrowUVecI32x4ToVecI16x8" narrowUVecI32x4ToVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenWidenLowSVecI8x16ToVecI16x8" widenLowSVecI8x16ToVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenWidenHighSVecI8x16ToVecI16x8" widenHighSVecI8x16ToVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenWidenLowUVecI8x16ToVecI16x8" widenLowUVecI8x16ToVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenWidenHighUVecI8x16ToVecI16x8" widenHighUVecI8x16ToVecI16x8 :: Op
+foreign import ccall unsafe "BinaryenWidenLowSVecI16x8ToVecI32x4" widenLowSVecI16x8ToVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenWidenHighSVecI16x8ToVecI32x4" widenHighSVecI16x8ToVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenWidenLowUVecI16x8ToVecI32x4" widenLowUVecI16x8ToVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenWidenHighUVecI16x8ToVecI32x4" widenHighUVecI16x8ToVecI32x4 :: Op
+foreign import ccall unsafe "BinaryenSwizzleVec8x16" swizzleVec8x16 :: Op
diff --git a/src/Binaryen/Relooper.hs b/src/Binaryen/Relooper.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/Relooper.hs
@@ -0,0 +1,60 @@
+-- | Control flow graph / relooper.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.Relooper where
+
+import Binaryen.Expression
+import Binaryen.Index
+import Binaryen.Module
+import Foreign (Ptr, Storable)
+
+newtype Relooper = Relooper (Ptr Relooper)
+  deriving (Eq, Show, Storable)
+
+newtype RelooperBlock = RelooperBlock (Ptr RelooperBlock)
+  deriving (Eq, Show)
+
+foreign import ccall unsafe "RelooperCreate"
+  create ::
+    Module -> IO Relooper
+
+foreign import ccall unsafe "RelooperAddBlock"
+  addBlock ::
+    Relooper -> Expression -> IO RelooperBlock
+
+foreign import ccall unsafe "RelooperAddBranch"
+  addBranch ::
+    RelooperBlock ->
+    RelooperBlock ->
+    Expression ->
+    Expression ->
+    IO ()
+
+foreign import ccall unsafe "RelooperAddBlockWithSwitch"
+  addBlockWithSwitch ::
+    Relooper ->
+    Expression ->
+    Expression ->
+    IO RelooperBlock
+
+foreign import ccall unsafe "RelooperAddBranchForSwitch"
+  addBranchForSwitch ::
+    RelooperBlock ->
+    RelooperBlock ->
+    Ptr Index ->
+    Index ->
+    Expression ->
+    IO ()
+
+foreign import ccall unsafe "RelooperRenderAndDispose"
+  renderAndDispose ::
+    Relooper ->
+    RelooperBlock ->
+    Index ->
+    IO Expression
diff --git a/src/Binaryen/SideEffects.hs b/src/Binaryen/SideEffects.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/SideEffects.hs
@@ -0,0 +1,36 @@
+-- | Effect analysis.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.SideEffects where
+
+import Binaryen.Expression
+import Binaryen.Features
+import Data.Word (Word32)
+import Foreign (Storable)
+
+newtype SideEffects = SideEffects Word32
+  deriving (Eq, Show, Storable)
+
+foreign import ccall unsafe "BinaryenSideEffectNone" none :: SideEffects
+foreign import ccall unsafe "BinaryenSideEffectBranches" branches :: SideEffects
+foreign import ccall unsafe "BinaryenSideEffectCalls" calls :: SideEffects
+foreign import ccall unsafe "BinaryenSideEffectReadsLocal" readsLocal :: SideEffects
+foreign import ccall unsafe "BinaryenSideEffectWritesLocal" writesLocal :: SideEffects
+foreign import ccall unsafe "BinaryenSideEffectReadsGlobal" readsGlobal :: SideEffects
+foreign import ccall unsafe "BinaryenSideEffectWritesGlobal" writesGlobal :: SideEffects
+foreign import ccall unsafe "BinaryenSideEffectReadsMemory" readsMemory :: SideEffects
+foreign import ccall unsafe "BinaryenSideEffectWritesMemory" writesMemory :: SideEffects
+foreign import ccall unsafe "BinaryenSideEffectImplicitTrap" implicitTrap :: SideEffects
+foreign import ccall unsafe "BinaryenSideEffectIsAtomic" isAtomic :: SideEffects
+foreign import ccall unsafe "BinaryenSideEffectThrows" throws :: SideEffects
+foreign import ccall unsafe "BinaryenSideEffectAny" any :: SideEffects
+
+foreign import ccall unsafe "BinaryenExpressionGetSideEffects"
+  getSideEffects ::
+    Expression -> Features -> IO SideEffects
diff --git a/src/Binaryen/Type.hs b/src/Binaryen/Type.hs
new file mode 100644
--- /dev/null
+++ b/src/Binaryen/Type.hs
@@ -0,0 +1,38 @@
+-- | Core types.
+--
+-- See <https://github.com/WebAssembly/binaryen/blob/master/src/binaryen-c.h>
+-- for API documentation.
+--
+-- This module is intended to be imported qualified.
+
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Binaryen.Type where
+
+import Data.Word (Word32)
+import Foreign (Ptr, Storable)
+
+newtype Type = Type Word32
+  deriving (Eq, Show, Storable)
+
+foreign import ccall unsafe "BinaryenTypeNone" none :: Type
+foreign import ccall unsafe "BinaryenTypeInt32" int32 :: Type
+foreign import ccall unsafe "BinaryenTypeInt64" int64 :: Type
+foreign import ccall unsafe "BinaryenTypeFloat32" float32 :: Type
+foreign import ccall unsafe "BinaryenTypeFloat64" float64 :: Type
+foreign import ccall unsafe "BinaryenTypeVec128" vec128 :: Type
+foreign import ccall unsafe "BinaryenTypeFuncref" funcref :: Type
+foreign import ccall unsafe "BinaryenTypeAnyref" anyref :: Type
+foreign import ccall unsafe "BinaryenTypeNullref" nullref :: Type
+foreign import ccall unsafe "BinaryenTypeExnref" exnref :: Type
+foreign import ccall unsafe "BinaryenTypeUnreachable" unreachable :: Type
+foreign import ccall unsafe "BinaryenTypeAuto" auto :: Type
+
+foreign import ccall unsafe "BinaryenTypeCreate"
+  create :: Ptr Type -> Word32 -> IO Type
+
+foreign import ccall unsafe "BinaryenTypeArity"
+  arity :: Type -> IO Word32
+
+foreign import ccall unsafe "BinaryenTypeExpand"
+  expand :: Type -> Ptr Type -> IO ()
