diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -14,7 +14,7 @@
 
 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
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 AUTHORS 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 IN THE
diff --git a/blas-hs.cabal b/blas-hs.cabal
--- a/blas-hs.cabal
+++ b/blas-hs.cabal
@@ -1,80 +1,111 @@
 name:                blas-hs
-version:             0.1.0.2
+version:             0.1.1.0
 synopsis:            Low-level Haskell bindings to Blas.
-description:         This package provides a complete low-level binding to
-                     Blas via the foreign function interface, allowing Haskell
-                     programs to take advantage of optimized routines for
-                     vector and matrix operations in Haskell.  See the source
-                     repository for more info.
+description:
+  This package provides a complete low-level binding to Blas via the foreign
+  function interface, allowing Haskell programs to take advantage of optimized
+  routines for vector and matrix operations in Haskell.
+  .
+  More information can be found at the
+  <https://github.com/Rufflewind/blas-hs repository>.
 homepage:            https://github.com/Rufflewind/blas-hs
 bug-reports:         https://github.com/Rufflewind/blas-hs/issues
 license:             MIT
 license-file:        LICENSE
 author:              Phil Ruffwind
 maintainer:          rf@rufflewind.com
+copyright:           (c) 2014 Phil Ruffwind
 category:            Math
 build-type:          Simple
-cabal-version:       >=1.16
-                     -- tested: 1.16 [hard] to 1.21 [soft]
-                     -- (limited by the test suite requirement on Cabal)
+cabal-version:       >=1.8
+                     -- *** 1.8 --- 1.14 === 1.21 ---
 
 source-repository head
   type:                git
   location:            https://github.com/Rufflewind/blas-hs
 
+flag no-netlib
+  description: Do not link with the reference Blas from Netlib.
+  default:     False
+flag no-accelerate
+  description: Do not link with the Accelerate Framework.  Has no effect
+               except on Darwin and Mac OS X.
+  default:     False
+flag openblas
+  description: Link with the OpenBLAS library.
+  default:     False
+flag mkl
+  description: Link with the Intel Math Kernel Library.
+  default:     False
+flag cblas
+  description: Link with the CBlas wrapper in addition to everything else.
+  default:     False
 
 library
+  hs-source-dirs:      src
   exposed-modules:     Blas.Primitive.Types
                        Blas.Primitive.Safe
                        Blas.Primitive.Unsafe
                        Blas.Generic.Safe
                        Blas.Generic.Unsafe
+                       Blas.Specialized.Float.Safe
+                       Blas.Specialized.Double.Safe
+                       Blas.Specialized.ComplexFloat.Safe
+                       Blas.Specialized.ComplexDouble.Safe
+                       Blas.Specialized.Float.Unsafe
+                       Blas.Specialized.Double.Unsafe
+                       Blas.Specialized.ComplexFloat.Unsafe
+                       Blas.Specialized.ComplexDouble.Unsafe
   other-modules:       BlasCTypes
                        FFI
   other-extensions:    FlexibleInstances
                      , ForeignFunctionInterface
                      , TypeFamilies
+  ghc-options:         -Wall
   build-depends:       base >=4.5 && <5
-                       -- tested: 4.5 [hard] to 4.8 [soft]
-                       -- (4.4 does not export constructors for CFloat et al)
+                       -- *** 4.5 === 4.8 ---
+                       -- 4.4 does not export constructors for CFloat et al
                      , storable-complex >=0.2 && <1
-                       -- tested: 0.2 [hard] to 0.3 [soft]
-                       -- (0.1 is buggy)
-  ghc-options:         -Wall
-  hs-source-dirs:      src
-  default-language:    Haskell98
+                       -- *** 0.2 === 0.3 ---
+                       -- 0.1 is buggy
 
-  -- Use the following flags if you want `blas-hs` to be directly linked
-  -- against an existing Blas implementation (e.g. ACML, OpenBLAS, MKL).  This
-  -- will relieve the `blas-hs` user of the responsibility of specifying the
-  -- flags for linking to the Blas implementation.
+  -- Both `extra-libraries` and `ld-options` control the linking of `blas-hs`
+  -- with the existing Blas implementation (e.g. ACML, OpenBLAS, MKL).
   --
-  -- The flags have no effect on the static version of `blas-hs`.
+  -- Note: If `blas-hs` is compiled as a static library, these flags have no
+  --       effect, so the user of `blas-hs` is then responsible for linking
+  --       against the libraries.
   --
-  -- Note: If these flags are specified and a shared library is built, omit
-  --       the corresponding flags in the test-suite (see below).
+
+  -- custom configuration
   extra-libraries:
   ld-options:
 
+  if flag(cblas)
+    extra-libraries: cblas
+  if flag(mkl)
+    -- Single Dynamic Library interface requires MKL 10.3+
+    extra-libraries: mkl_rt pthread m
+    ld-options:      -fopenmp
+  else
+    if flag(openblas)
+      extra-libraries: openblas
+    else
+      if (os(darwin) || os(osx)) && !flag(no-accelerate)
+        frameworks:      Accelerate
+      else
+        if !flag(no-netlib)
+          extra-libraries: blas
+
 test-suite test
-  type:                detailed-0.9
-  test-module:         MainTest
+  hs-source-dirs:      tests
+  type:                exitcode-stdio-1.0
+  main-is:             MainTest.hs
   other-extensions:    Rank2Types
+  other-modules:       TestUtils
   build-depends:       base
                      , blas-hs
 
-                     , Cabal >=1.16
-                       -- tested: 1.16 [hard] to 1.21 [soft]
-                       -- (0.15 does not have Progress)
-
-                     , vector >=0.8
-                       -- tested: 0.8 [hard] to 0.11 [soft]
-                       -- (0.7 has a different definition of MVector)
-
-  hs-source-dirs:      tests
-  default-language:    Haskell98
-
-  -- Note: Omit these flags if they are specified by the library and a shared
-  --       library is built (see above).
-  extra-libraries:     blas
-  ld-options:
+                     , vector >=0.8 && <1
+                       -- *** 0.8 === 0.11 ---
+                       -- 0.7 has a different definition of MVector
diff --git a/src/Blas/Generic/Safe.hs b/src/Blas/Generic/Safe.hs
--- a/src/Blas/Generic/Safe.hs
+++ b/src/Blas/Generic/Safe.hs
@@ -1,309 +1,765 @@
-{- This file is auto-generated.  Do not edit directly. -}
-{-# LANGUAGE FlexibleInstances, TypeFamilies #-}
-{-|
-
-Stability: experimental
-
-Generic interface to Blas using safe foreign calls.  Refer to
-the GHC documentation for more information regarding appropriate use of safe
-and unsafe foreign calls.
-
-The functions here are named in a similar fashion to the original Blas
-interface, with the type-dependent letter(s) removed.  Some functions have
-been merged with others to allow the interface to work on both real and
-complex numbers.  If you can't a particular function, try looking for its
-corresponding complex equivalent (e.g. @symv@ is a special case of 'hemv'
-applied to real numbers).
-
-It'd be really nice if these functions were actually documented.  Alas, for
-the time being, you'll have to refer to the various Blas docs scattered across
-the Internet.  Note that the interface is based off of /CBlas/, not Fortran
-Blas, which is slightly different.
-
--}
-module Blas.Generic.Safe
-       ( Numeric(..)
-       , RealNumeric(..)
-       , C.dsdot
-       , C.sdsdot
-       ) where
-import Data.Complex (Complex((:+)))
-import Foreign (Ptr, Storable)
-import FFI (getReturnValue)
-import Blas.Primitive.Types (Order, Transpose, Uplo, Diag, Side)
-import qualified Blas.Primitive.Safe as C
-
--- | Blas operations that are applicable to real and complex numbers.
---
---   Instances are defined for the 4 types supported by Blas: the
---   single- and double-precision floating point types and their complex
---   versions.
-class (Floating a, Storable a) => Numeric a where
-
-  -- | The corresponding real type of @a@.
-  --
-  --   In other words, @'RealType' ('Complex' a)@ is an alias for @a@.  For
-  --   everything else, @'RealType' a@ is simply @a@.
-  type RealType a :: *
-
-  dotu  :: Int -> Ptr a -> Int -> Ptr a -> Int -> IO a
-  dotc  :: Int -> Ptr a -> Int -> Ptr a -> Int -> IO a
-  nrm2  :: Int -> Ptr a -> Int -> IO (RealType a)
-  asum  :: Int -> Ptr a -> Int -> IO (RealType a)
-  iamax :: Int -> Ptr a -> Int -> IO Int
-  swap  :: Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()
-  copy  :: Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()
-  axpy  :: Int -> a -> Ptr a -> Int -> Ptr a -> Int -> IO ()
-  scal  :: Int -> a -> Ptr a -> Int -> IO ()
-  gemv  :: Order -> Transpose -> Int -> Int -> a -> Ptr a -> Int -> Ptr a
-        -> Int -> a -> Ptr a -> Int -> IO ()
-  gbmv  :: Order -> Transpose -> Int -> Int -> Int -> Int -> a -> Ptr a
-        -> Int -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()
-  trmv  :: Order -> Uplo -> Transpose -> Diag -> Int -> Ptr a -> Int
-        -> Ptr a -> Int -> IO ()
-  tbmv  :: Order -> Uplo -> Transpose -> Diag -> Int -> Int -> Ptr a
-        -> Int -> Ptr a -> Int -> IO ()
-  tpmv  :: Order -> Uplo -> Transpose -> Diag -> Int -> Ptr a -> Ptr a
-        -> Int -> IO ()
-  trsv  :: Order -> Uplo -> Transpose -> Diag -> Int -> Ptr a -> Int
-        -> Ptr a -> Int -> IO ()
-  tbsv  :: Order -> Uplo -> Transpose -> Diag -> Int -> Int -> Ptr a
-        -> Int -> Ptr a -> Int -> IO ()
-  tpsv  :: Order -> Uplo -> Transpose -> Diag -> Int -> Ptr a -> Ptr a
-        -> Int -> IO ()
-  hemv  :: Order -> Uplo -> Int -> a -> Ptr a -> Int -> Ptr a -> Int
-        -> a -> Ptr a -> Int -> IO ()
-  hbmv  :: Order -> Uplo -> Int -> Int -> a -> Ptr a -> Int -> Ptr a
-        -> Int -> a -> Ptr a -> Int -> IO ()
-  hpmv  :: Order -> Uplo -> Int -> a -> Ptr a -> Ptr a -> Int -> a
-        -> Ptr a -> Int -> IO ()
-  geru  :: Order -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int
-        -> Ptr a -> Int -> IO ()
-  gerc  :: Order -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int
-        -> Ptr a -> Int -> IO ()
-  her   :: Order -> Uplo -> Int -> RealType a -> Ptr a -> Int
-        -> Ptr a -> Int -> IO ()
-  hpr   :: Order -> Uplo -> Int -> RealType a -> Ptr a -> Int
-        -> Ptr a -> IO ()
-  her2  :: Order -> Uplo -> Int -> a -> Ptr a -> Int -> Ptr a -> Int
-        -> Ptr a -> Int -> IO ()
-  hpr2  :: Order -> Uplo -> Int -> a -> Ptr a -> Int -> Ptr a -> Int
-        -> Ptr a -> IO ()
-
-  -- | Calculate a general matrix-matrix product:
-  --
-  --   > c := alpha * opa(a) * opb(b) + beta * c
-  --
-  --   where `opa` and `opb` are operations specified by @transa@ and
-  --   @transb@ respectively.
-  gemm  :: Order     -- ^ Layout of all matrices.
-        -> Transpose -- ^ (@transa@) Operation applied to @a@.
-        -> Transpose -- ^ (@transb@) Operation applied to @b@.
-        -> Int       -- ^ (@m@) Number of rows of @op(a)@ and @c@.
-        -> Int       -- ^ (@n@) Number of columns of @op(b)@ and @c@.
-        -> Int       -- ^ (@k@) Number of columns of @op(a)@ and
-                     --         number of of rows of @op(b)@.
-        -> a         -- ^ (@alpha@) Scaling factor of the product.
-        -> Ptr a     -- ^ (@a@) Pointer to a matrix.
-        -> Int       -- ^ (@lda@) Stride of the major dimension of @a@.
-        -> Ptr a     -- ^ (@b@) Pointer to a matrix.
-        -> Int       -- ^ (@ldb@) Stride of the major dimension of @b@.
-        -> a         -- ^ (@beta@) Scaling factor of the original @c@.
-        -> Ptr a     -- ^ (@c@) Pointer to a mutable matrix.
-        -> Int       -- ^ (@ldc@) Stride of the major dimension of @c@.
-        -> IO ()
-
-  symm  :: Order -> Side -> Uplo -> Int -> Int -> a -> Ptr a -> Int
-        -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()
-  syrk  :: Order -> Uplo -> Transpose -> Int -> Int -> a -> Ptr a -> Int
-        -> a -> Ptr a -> Int -> IO ()
-  syr2k :: Order -> Uplo -> Transpose -> Int -> Int -> a -> Ptr a -> Int
-        -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()
-  hemm  :: Order -> Side -> Uplo -> Int -> Int -> a -> Ptr a -> Int
-        -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()
-  herk  :: Order -> Uplo -> Transpose -> Int -> Int -> RealType a -> Ptr a
-        -> Int -> RealType a -> Ptr a -> Int -> IO ()
-  her2k :: Order -> Uplo -> Transpose -> Int -> Int -> a -> Ptr a -> Int
-        -> Ptr a -> Int -> RealType a -> Ptr a -> Int -> IO ()
-  trmm  :: Order -> Side -> Uplo -> Transpose -> Diag -> Int -> Int
-        -> a -> Ptr a -> Int -> Ptr a -> Int -> IO ()
-  trsm  :: Order -> Side -> Uplo -> Transpose -> Diag -> Int -> Int
-        -> a -> Ptr a -> Int -> Ptr a -> Int -> IO ()
-
--- | Blas operations that are only applicable to real numbers.
---
---   Note: although complex versions of 'rot' and 'rotg' exist in many
---   implementations, they are not part of the official Blas standard and
---   therefore not included here.  If you /really/ need them, submit a ticket
---   so we can try to come up with a solution.
-class Numeric a => RealNumeric a where
-  rotg  :: Ptr a -> Ptr a -> Ptr a -> Ptr a -> IO ()
-  rotmg :: Ptr a -> Ptr a -> Ptr a -> a -> Ptr a -> IO ()
-  rot   :: Int -> Ptr a -> Int -> Ptr a -> Int -> a -> a -> IO ()
-  rotm  :: Int -> Ptr a -> Int -> Ptr a -> Int -> Ptr a -> IO ()
-
-instance Numeric Float where
-  type RealType Float = Float
-  dotu  = C.sdot
-  dotc  = C.sdot
-  nrm2  = C.snrm2
-  asum  = C.sasum
-  iamax = C.isamax
-  swap  = C.sswap
-  copy  = C.scopy
-  axpy  = C.saxpy
-  scal  = C.sscal
-  gemv  = C.sgemv
-  gbmv  = C.sgbmv
-  trmv  = C.strmv
-  tbmv  = C.stbmv
-  tpmv  = C.stpmv
-  trsv  = C.strsv
-  tbsv  = C.stbsv
-  tpsv  = C.stpsv
-  hemv  = C.ssymv
-  hbmv  = C.ssbmv
-  hpmv  = C.sspmv
-  geru  = C.sger
-  gerc  = C.sger
-  her   = C.ssyr
-  hpr   = C.sspr
-  her2  = C.ssyr2
-  hpr2  = C.sspr2
-  gemm  = C.sgemm
-  symm  = C.ssymm
-  hemm  = C.ssymm
-  syrk  = C.ssyrk
-  herk  = C.ssyrk
-  syr2k = C.ssyr2k
-  her2k = C.ssyr2k
-  trmm  = C.strmm
-  trsm  = C.strsm
-
-instance RealNumeric Float where
-  rotg  = C.srotg
-  rotmg = C.srotmg
-  rot   = C.srot
-  rotm  = C.srotm
-
-instance Numeric Double where
-  type RealType Double = Double
-  dotu  = C.ddot
-  dotc  = C.ddot
-  nrm2  = C.dnrm2
-  asum  = C.dasum
-  iamax = C.idamax
-  swap  = C.dswap
-  copy  = C.dcopy
-  axpy  = C.daxpy
-  scal  = C.dscal
-  gemv  = C.dgemv
-  gbmv  = C.dgbmv
-  trmv  = C.dtrmv
-  tbmv  = C.dtbmv
-  tpmv  = C.dtpmv
-  trsv  = C.dtrsv
-  tbsv  = C.dtbsv
-  tpsv  = C.dtpsv
-  hemv  = C.dsymv
-  hbmv  = C.dsbmv
-  hpmv  = C.dspmv
-  geru  = C.dger
-  gerc  = C.dger
-  her   = C.dsyr
-  hpr   = C.dspr
-  her2  = C.dsyr2
-  hpr2  = C.dspr2
-  gemm  = C.dgemm
-  symm  = C.dsymm
-  hemm  = C.dsymm
-  syrk  = C.dsyrk
-  herk  = C.dsyrk
-  syr2k = C.dsyr2k
-  her2k = C.dsyr2k
-  trmm  = C.dtrmm
-  trsm  = C.dtrsm
-
-instance RealNumeric Double where
-  rotg  = C.drotg
-  rotmg = C.drotmg
-  rot   = C.drot
-  rotm  = C.drotm
-
-instance Numeric (Complex Float) where
-  type RealType (Complex Float) = Float
-  dotu a b c d e = getReturnValue (C.cdotu_sub a b c d e)
-  dotc a b c d e = getReturnValue (C.cdotc_sub a b c d e)
-  nrm2  = C.scnrm2
-  asum  = C.scasum
-  iamax = C.icamax
-  swap  = C.cswap
-  copy  = C.ccopy
-  axpy  = C.caxpy
-  scal n (alpha :+ 0) = C.csscal n alpha
-  scal n  alpha       = C.cscal  n alpha
-  gemv  = C.cgemv
-  gbmv  = C.cgbmv
-  trmv  = C.ctrmv
-  tbmv  = C.ctbmv
-  tpmv  = C.ctpmv
-  trsv  = C.ctrsv
-  tbsv  = C.ctbsv
-  tpsv  = C.ctpsv
-  hemv  = C.chemv
-  hbmv  = C.chbmv
-  hpmv  = C.chpmv
-  geru  = C.cgeru
-  gerc  = C.cgerc
-  her   = C.cher
-  hpr   = C.chpr
-  her2  = C.cher2
-  hpr2  = C.chpr2
-  gemm  = C.cgemm
-  symm  = C.csymm
-  hemm  = C.chemm
-  syrk  = C.csyrk
-  herk  = C.cherk
-  syr2k = C.csyr2k
-  her2k = C.cher2k
-  trmm  = C.ctrmm
-  trsm  = C.ctrsm
-
-instance Numeric (Complex Double) where
-  type RealType (Complex Double) = Double
-  dotu a b c d e = getReturnValue (C.zdotu_sub a b c d e)
-  dotc a b c d e = getReturnValue (C.zdotc_sub a b c d e)
-  nrm2  = C.dznrm2
-  asum  = C.dzasum
-  iamax = C.izamax
-  swap  = C.zswap
-  copy  = C.zcopy
-  axpy  = C.zaxpy
-  scal n (alpha :+ 0) = C.zdscal n alpha
-  scal n  alpha       = C.zscal  n alpha
-  gemv  = C.zgemv
-  gbmv  = C.zgbmv
-  trmv  = C.ztrmv
-  tbmv  = C.ztbmv
-  tpmv  = C.ztpmv
-  trsv  = C.ztrsv
-  tbsv  = C.ztbsv
-  tpsv  = C.ztpsv
-  hemv  = C.zhemv
-  hbmv  = C.zhbmv
-  hpmv  = C.zhpmv
-  geru  = C.zgeru
-  gerc  = C.zgerc
-  her   = C.zher
-  hpr   = C.zhpr
-  her2  = C.zher2
-  hpr2  = C.zhpr2
-  gemm  = C.zgemm
-  symm  = C.zsymm
-  hemm  = C.zhemm
-  syrk  = C.zsyrk
-  herk  = C.zherk
-  syr2k = C.zsyr2k
-  her2k = C.zher2k
-  trmm  = C.ztrmm
-  trsm  = C.ztrsm
+-- This file is auto-generated.  Do not edit directly.
+-- |
+--   Stability: Experimental
+--
+--   Generic interface to Blas using safe foreign calls.  Refer to the GHC documentation
+--   for more information regarding appropriate use of safe and unsafe foreign calls.
+--
+--   The functions here are named in a similar fashion to the original Blas interface, with
+--   the type-dependent letter(s) removed.  Some functions have been merged with
+--   others to allow the interface to work on both real and complex numbers.  If you can't a
+--   particular function, try looking for its corresponding complex equivalent (e.g.
+--   @symv@ is a special case of 'hemv' applied to real numbers).
+--
+--   Note: although complex versions of 'rot' and 'rotg' exist in many implementations,
+--   they are not part of the official Blas standard and therefore not included here.  If
+--   you /really/ need them, submit a ticket so we can try to come up with a solution.
+--
+--   The documentation here is still incomplete.  Consult the
+--   <http://netlib.org/blas/#_blas_routines official documentation> for more
+--   information.
+--
+--   Notation:
+--
+--     * @⋅@ denotes dot product (without any conjugation).
+--     * @*@ denotes complex conjugation.
+--     * @⊤@ denotes transpose.
+--     * @†@ denotes conjugate transpose (Hermitian conjugate).
+--
+--   Conventions:
+--
+--     * All scalars are denoted with lowercase Greek letters
+--     * All vectors are denoted with lowercase Latin letters and are
+--       assumed to be column vectors (unless transposed).
+--     * All matrices are denoted with uppercase Latin letters.
+{-# LANGUAGE FlexibleInstances, TypeFamilies #-}
+module Blas.Generic.Safe (
+    Numeric(..)
+  , RealNumeric(..)
+  , D.dsdot
+  , S.sdsdot
+  ) where
+import Data.Complex (Complex)
+import Foreign (Ptr, Storable)
+import Blas.Primitive.Types (Order, Transpose, Uplo, Diag, Side)
+import qualified Blas.Specialized.Float.Safe as S
+import qualified Blas.Specialized.Double.Safe as D
+import qualified Blas.Specialized.ComplexFloat.Safe as C
+import qualified Blas.Specialized.ComplexDouble.Safe as Z
+
+-- | Blas operations that are applicable to real and complex numbers.
+--
+--   Instances are defined for the 4 types supported by Blas: the single- and
+--   double-precision floating point types and their complex versions.
+class (Floating a, Storable a) => Numeric a where
+
+  -- | The corresponding real type of @a@.
+  --
+  --   In other words, @'RealType' ('Complex' a)@ is an alias for @a@.  For everything
+  --   else, @'RealType' a@ is simply @a@.
+  type RealType a :: *
+  -- | Swap two vectors:
+  --
+  --   > (x, y) ← (y, x)
+  swap :: Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply a vector by a scalar.
+  --
+  --   > x ← α x
+  scal :: Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Copy a vector into another vector:
+  --
+  --   > y ← x
+  copy :: Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Add a scalar-vector product to a vector.
+  --
+  --   > y ← α x + y
+  axpy :: Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Calculate the bilinear dot product of two vectors:
+  --
+  --   > x ⋅ y ≡ ∑[i] x[i] y[i]
+  dotu :: Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO a
+
+  -- | Calculate the sesquilinear dot product of two vectors.
+  --
+  --   > x* ⋅ y ≡ ∑[i] x[i]* y[i]
+  dotc :: Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO a
+
+  -- | Calculate the Euclidean (L²) norm of a vector:
+  --
+  --   > ‖x‖₂ ≡ √(∑[i] x[i]²)
+  nrm2 :: Int
+       -> Ptr a
+       -> Int
+       -> IO (RealType a)
+
+  -- | Calculate the Manhattan (L¹) norm, equal to the sum of the magnitudes of the elements:
+  --
+  --   > ‖x‖₁ = ∑[i] |x[i]|
+  asum :: Int
+       -> Ptr a
+       -> Int
+       -> IO (RealType a)
+
+  -- | Calculate the index of the element with the maximum magnitude (absolute value).
+  iamax :: Int
+        -> Ptr a
+        -> Int
+        -> IO Int
+
+  -- | Perform a general matrix-vector update.
+  --
+  --   > y ← α T(A) x + β y
+  gemv :: Order
+       -> Transpose
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a general banded matrix-vector update.
+  --
+  --   > y ← α T(A) x + β y
+  gbmv :: Order
+       -> Transpose
+       -> Int
+       -> Int
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a hermitian matrix-vector update.
+  --
+  --   > y ← α A x + β y
+  hemv :: Order
+       -> Uplo
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a hermitian banded matrix-vector update.
+  --
+  --   > y ← α A x + β y
+  hbmv :: Order
+       -> Uplo
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a hermitian packed matrix-vector update.
+  --
+  --   > y ← α A x + β y
+  hpmv :: Order
+       -> Uplo
+       -> Int
+       -> a
+       -> Ptr a
+       -> Ptr a
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply a triangular matrix by a vector.
+  --
+  --   > x ← T(A) x
+  trmv :: Order
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply a triangular banded matrix by a vector.
+  --
+  --   > x ← T(A) x
+  tbmv :: Order
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply a triangular packed matrix by a vector.
+  --
+  --   > x ← T(A) x
+  tpmv :: Order
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Ptr a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply an inverse triangular matrix by a vector.
+  --
+  --   > x ← T(A⁻¹) x
+  trsv :: Order
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply an inverse triangular banded matrix by a vector.
+  --
+  --   > x ← T(A⁻¹) x
+  tbsv :: Order
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply an inverse triangular packed matrix by a vector.
+  --
+  --   > x ← T(A⁻¹) x
+  tpsv :: Order
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Ptr a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform an unconjugated rank-1 update of a general matrix.
+  --
+  --   > A ← α x y⊤ + A
+  geru :: Order
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a conjugated rank-1 update of a general matrix.
+  --
+  --   > A ← α x y† + A
+  gerc :: Order
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a rank-1 update of a Hermitian matrix.
+  --
+  --   > A ← α x y† + A
+  her :: Order
+      -> Uplo
+      -> Int
+      -> RealType a
+      -> Ptr a
+      -> Int
+      -> Ptr a
+      -> Int
+      -> IO ()
+
+  -- | Perform a rank-1 update of a Hermitian packed matrix.
+  --
+  --   > A ← α x y† + A
+  hpr :: Order
+      -> Uplo
+      -> Int
+      -> RealType a
+      -> Ptr a
+      -> Int
+      -> Ptr a
+      -> IO ()
+
+  -- | Perform a rank-2 update of a Hermitian matrix.
+  --
+  --   > A ← α x y† + y (α x)† + A
+  her2 :: Order
+       -> Uplo
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a rank-2 update of a Hermitian packed matrix.
+  --
+  --   > A ← α x y† + y (α x)† + A
+  hpr2 :: Order
+       -> Uplo
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> IO ()
+
+  -- | Perform a general matrix-matrix update.
+  --
+  --   > C ← α T(A) U(B) + β C
+  gemm :: Order -- ^ Layout of all the matrices.
+       -> Transpose -- ^ The operation @T@ to be applied to @A@.
+       -> Transpose -- ^ The operation @U@ to be applied to @B@.
+       -> Int -- ^ Number of rows of @T(A)@ and @C@.
+       -> Int -- ^ Number of columns of @U(B)@ and @C@.
+       -> Int -- ^ Number of columns of @T(A)@ and number of rows of @U(B)@.
+       -> a -- ^ Scaling factor @α@ of the product.
+       -> Ptr a -- ^ Pointer to a matrix @A@.
+       -> Int -- ^ Stride of the major dimension of @A@.
+       -> Ptr a -- ^ Pointer to a matrix @B@.
+       -> Int -- ^ Stride of the major dimension of @B@.
+       -> a -- ^ Scaling factor @β@ of the original @C@.
+       -> Ptr a -- ^ Pointer to a mutable matrix @C@.
+       -> Int -- ^ Stride of the major dimension of @C@.
+       -> IO ()
+
+  -- | Perform a symmetric matrix-matrix update.
+  --
+  --   > C ← α A B + β C    or    C ← α B A + β C
+  --
+  --   where @A@ is symmetric.  The matrix @A@ must be in an unpacked format, although the
+  --   routine will only access half of it as specified by the @'Uplo'@ argument.
+  symm :: Order -- ^ Layout of all the matrices.
+       -> Side -- ^ Side that @A@ appears in the product.
+       -> Uplo -- ^ The part of @A@ that is used.
+       -> Int -- ^ Number of rows of @C@.
+       -> Int -- ^ Number of columns of @C@.
+       -> a -- ^ Scaling factor @α@ of the product.
+       -> Ptr a -- ^ Pointer to a symmetric matrix @A@.
+       -> Int -- ^ Stride of the major dimension of @A@.
+       -> Ptr a -- ^ Pointer to a matrix @B@.
+       -> Int -- ^ Stride of the major dimension of @B@.
+       -> a -- ^ Scaling factor @α@ of the original @C@.
+       -> Ptr a -- ^ Pointer to a mutable matrix @C@.
+       -> Int -- ^ Stride of the major dimension of @C@.
+       -> IO ()
+
+  -- | Perform a Hermitian matrix-matrix update.
+  --
+  --   > C ← α A B + β C    or    C ← α B A + β C
+  --
+  --   where @A@ is Hermitian.  The matrix @A@ must be in an unpacked format, although the
+  --   routine will only access half of it as specified by the @'Uplo'@ argument.
+  hemm :: Order -- ^ Layout of all the matrices.
+       -> Side -- ^ Side that @A@ appears in the product.
+       -> Uplo -- ^ The part of @A@ that is used.
+       -> Int -- ^ Number of rows of @C@.
+       -> Int -- ^ Number of columns of @C@.
+       -> a -- ^ Scaling factor @α@ of the product.
+       -> Ptr a -- ^ Pointer to a Hermitian matrix @A@.
+       -> Int -- ^ Stride of the major dimension of @A@.
+       -> Ptr a -- ^ Pointer to a matrix @B@.
+       -> Int -- ^ Stride of the major dimension of @B@.
+       -> a -- ^ Scaling factor @α@ of the original @C@.
+       -> Ptr a -- ^ Pointer to a mutable matrix @C@.
+       -> Int -- ^ Stride of the major dimension of @C@.
+       -> IO ()
+
+  -- | Perform a symmetric rank-k update.
+  --
+  --   > C ← α A A⊤ + β C    or    C ← α A⊤ A + β C
+  syrk :: Order
+       -> Uplo
+       -> Transpose
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a Hermitian rank-k update.
+  --
+  --   > C ← α A A† + β C    or    C ← α A† A + β C
+  herk :: Order
+       -> Uplo
+       -> Transpose
+       -> Int
+       -> Int
+       -> RealType a
+       -> Ptr a
+       -> Int
+       -> RealType a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a symmetric rank-2k update.
+  --
+  --   > C ← α A B⊤ + α* B A⊤ + β C    or    C ← α A⊤ B + α* B⊤ A + β C
+  syr2k :: Order
+        -> Uplo
+        -> Transpose
+        -> Int
+        -> Int
+        -> a
+        -> Ptr a
+        -> Int
+        -> Ptr a
+        -> Int
+        -> a
+        -> Ptr a
+        -> Int
+        -> IO ()
+
+  -- | Perform a Hermitian rank-2k update.
+  --
+  --   > C ← α A B† + α* B A† + β C    or    C ← α A† B + α* B† A + β C
+  her2k :: Order
+        -> Uplo
+        -> Transpose
+        -> Int
+        -> Int
+        -> a
+        -> Ptr a
+        -> Int
+        -> Ptr a
+        -> Int
+        -> RealType a
+        -> Ptr a
+        -> Int
+        -> IO ()
+
+  -- | Perform a triangular matrix-matrix multiplication.
+  --
+  --   > B ← α T(A) B    or    B ← α B T(A)
+  --
+  --   where @A@ is triangular.
+  trmm :: Order
+       -> Side
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform an inverse triangular matrix-matrix multiplication.
+  --
+  --   > B ← α T(A⁻¹) B    or    B ← α B T(A⁻¹)
+  --
+  --   where @A@ is triangular.
+  trsm :: Order
+       -> Side
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+-- | Blas operations that are only applicable to real numbers.
+class Numeric a => RealNumeric a where
+
+  -- | Generate a Givens rotation. (Only available for real floating-point types.)
+  rotg :: Ptr a
+       -> Ptr a
+       -> Ptr a
+       -> Ptr a
+       -> IO ()
+
+  -- | Generate a modified Givens rotation. (Only available for real floating-point
+  --   types.)
+  rotmg :: Ptr a
+        -> Ptr a
+        -> Ptr a
+        -> a
+        -> Ptr a
+        -> IO ()
+
+  -- | Apply a Givens rotation. (Only available for real floating-point types.)
+  rot :: Int
+      -> Ptr a
+      -> Int
+      -> Ptr a
+      -> Int
+      -> a
+      -> a
+      -> IO ()
+
+  -- | Apply a modified Givens rotation. (Only available for real floating-point types.)
+  rotm :: Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> IO ()
+
+instance Numeric Float where
+  type RealType Float = Float
+  swap = S.swap
+  scal = S.scal
+  copy = S.copy
+  axpy = S.axpy
+  dotu = S.dotu
+  dotc = S.dotc
+  nrm2 = S.nrm2
+  asum = S.asum
+  iamax = S.iamax
+  gemv = S.gemv
+  gbmv = S.gbmv
+  hemv = S.hemv
+  hbmv = S.hbmv
+  hpmv = S.hpmv
+  trmv = S.trmv
+  tbmv = S.tbmv
+  tpmv = S.tpmv
+  trsv = S.trsv
+  tbsv = S.tbsv
+  tpsv = S.tpsv
+  geru = S.geru
+  gerc = S.gerc
+  her = S.her
+  hpr = S.hpr
+  her2 = S.her2
+  hpr2 = S.hpr2
+  gemm = S.gemm
+  symm = S.symm
+  hemm = S.hemm
+  syrk = S.syrk
+  herk = S.herk
+  syr2k = S.syr2k
+  her2k = S.her2k
+  trmm = S.trmm
+  trsm = S.trsm
+
+
+instance Numeric Double where
+  type RealType Double = Double
+  swap = D.swap
+  scal = D.scal
+  copy = D.copy
+  axpy = D.axpy
+  dotu = D.dotu
+  dotc = D.dotc
+  nrm2 = D.nrm2
+  asum = D.asum
+  iamax = D.iamax
+  gemv = D.gemv
+  gbmv = D.gbmv
+  hemv = D.hemv
+  hbmv = D.hbmv
+  hpmv = D.hpmv
+  trmv = D.trmv
+  tbmv = D.tbmv
+  tpmv = D.tpmv
+  trsv = D.trsv
+  tbsv = D.tbsv
+  tpsv = D.tpsv
+  geru = D.geru
+  gerc = D.gerc
+  her = D.her
+  hpr = D.hpr
+  her2 = D.her2
+  hpr2 = D.hpr2
+  gemm = D.gemm
+  symm = D.symm
+  hemm = D.hemm
+  syrk = D.syrk
+  herk = D.herk
+  syr2k = D.syr2k
+  her2k = D.her2k
+  trmm = D.trmm
+  trsm = D.trsm
+
+
+instance Numeric (Complex Float) where
+  type RealType (Complex Float) = Float
+  swap = C.swap
+  scal = C.scal
+  copy = C.copy
+  axpy = C.axpy
+  dotu = C.dotu
+  dotc = C.dotc
+  nrm2 = C.nrm2
+  asum = C.asum
+  iamax = C.iamax
+  gemv = C.gemv
+  gbmv = C.gbmv
+  hemv = C.hemv
+  hbmv = C.hbmv
+  hpmv = C.hpmv
+  trmv = C.trmv
+  tbmv = C.tbmv
+  tpmv = C.tpmv
+  trsv = C.trsv
+  tbsv = C.tbsv
+  tpsv = C.tpsv
+  geru = C.geru
+  gerc = C.gerc
+  her = C.her
+  hpr = C.hpr
+  her2 = C.her2
+  hpr2 = C.hpr2
+  gemm = C.gemm
+  symm = C.symm
+  hemm = C.hemm
+  syrk = C.syrk
+  herk = C.herk
+  syr2k = C.syr2k
+  her2k = C.her2k
+  trmm = C.trmm
+  trsm = C.trsm
+
+
+instance Numeric (Complex Double) where
+  type RealType (Complex Double) = Double
+  swap = Z.swap
+  scal = Z.scal
+  copy = Z.copy
+  axpy = Z.axpy
+  dotu = Z.dotu
+  dotc = Z.dotc
+  nrm2 = Z.nrm2
+  asum = Z.asum
+  iamax = Z.iamax
+  gemv = Z.gemv
+  gbmv = Z.gbmv
+  hemv = Z.hemv
+  hbmv = Z.hbmv
+  hpmv = Z.hpmv
+  trmv = Z.trmv
+  tbmv = Z.tbmv
+  tpmv = Z.tpmv
+  trsv = Z.trsv
+  tbsv = Z.tbsv
+  tpsv = Z.tpsv
+  geru = Z.geru
+  gerc = Z.gerc
+  her = Z.her
+  hpr = Z.hpr
+  her2 = Z.her2
+  hpr2 = Z.hpr2
+  gemm = Z.gemm
+  symm = Z.symm
+  hemm = Z.hemm
+  syrk = Z.syrk
+  herk = Z.herk
+  syr2k = Z.syr2k
+  her2k = Z.her2k
+  trmm = Z.trmm
+  trsm = Z.trsm
+instance RealNumeric Float where
+  rotg = S.rotg
+  rotmg = S.rotmg
+  rot = S.rot
+  rotm = S.rotm
+
+
+instance RealNumeric Double where
+  rotg = D.rotg
+  rotmg = D.rotmg
+  rot = D.rot
+  rotm = D.rotm
diff --git a/src/Blas/Generic/Unsafe.hs b/src/Blas/Generic/Unsafe.hs
--- a/src/Blas/Generic/Unsafe.hs
+++ b/src/Blas/Generic/Unsafe.hs
@@ -1,309 +1,766 @@
-{- This file is auto-generated.  Do not edit directly. -}
-{-# LANGUAGE FlexibleInstances, TypeFamilies #-}
-{-|
-
-Stability: experimental
-
-Generic interface to Blas using unsafe foreign calls.  Refer to
-the GHC documentation for more information regarding appropriate use of safe
-and unsafe foreign calls.
-
-The functions here are named in a similar fashion to the original Blas
-interface, with the type-dependent letter(s) removed.  Some functions have
-been merged with others to allow the interface to work on both real and
-complex numbers.  If you can't a particular function, try looking for its
-corresponding complex equivalent (e.g. @symv@ is a special case of 'hemv'
-applied to real numbers).
-
-It'd be really nice if these functions were actually documented.  Alas, for
-the time being, you'll have to refer to the various Blas docs scattered across
-the Internet.  Note that the interface is based off of /CBlas/, not Fortran
-Blas, which is slightly different.
-
--}
-module Blas.Generic.Unsafe
-       ( Numeric(..)
-       , RealNumeric(..)
-       , C.dsdot
-       , C.sdsdot
-       ) where
-import Data.Complex (Complex((:+)))
-import Foreign (Ptr, Storable)
-import FFI (getReturnValue)
-import Blas.Primitive.Types (Order, Transpose, Uplo, Diag, Side)
-import qualified Blas.Primitive.Unsafe as C
-
--- | Blas operations that are applicable to real and complex numbers.
---
---   Instances are defined for the 4 types supported by Blas: the
---   single- and double-precision floating point types and their complex
---   versions.
-class (Floating a, Storable a) => Numeric a where
-
-  -- | The corresponding real type of @a@.
-  --
-  --   In other words, @'RealType' ('Complex' a)@ is an alias for @a@.  For
-  --   everything else, @'RealType' a@ is simply @a@.
-  type RealType a :: *
-
-  dotu  :: Int -> Ptr a -> Int -> Ptr a -> Int -> IO a
-  dotc  :: Int -> Ptr a -> Int -> Ptr a -> Int -> IO a
-  nrm2  :: Int -> Ptr a -> Int -> IO (RealType a)
-  asum  :: Int -> Ptr a -> Int -> IO (RealType a)
-  iamax :: Int -> Ptr a -> Int -> IO Int
-  swap  :: Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()
-  copy  :: Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()
-  axpy  :: Int -> a -> Ptr a -> Int -> Ptr a -> Int -> IO ()
-  scal  :: Int -> a -> Ptr a -> Int -> IO ()
-  gemv  :: Order -> Transpose -> Int -> Int -> a -> Ptr a -> Int -> Ptr a
-        -> Int -> a -> Ptr a -> Int -> IO ()
-  gbmv  :: Order -> Transpose -> Int -> Int -> Int -> Int -> a -> Ptr a
-        -> Int -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()
-  trmv  :: Order -> Uplo -> Transpose -> Diag -> Int -> Ptr a -> Int
-        -> Ptr a -> Int -> IO ()
-  tbmv  :: Order -> Uplo -> Transpose -> Diag -> Int -> Int -> Ptr a
-        -> Int -> Ptr a -> Int -> IO ()
-  tpmv  :: Order -> Uplo -> Transpose -> Diag -> Int -> Ptr a -> Ptr a
-        -> Int -> IO ()
-  trsv  :: Order -> Uplo -> Transpose -> Diag -> Int -> Ptr a -> Int
-        -> Ptr a -> Int -> IO ()
-  tbsv  :: Order -> Uplo -> Transpose -> Diag -> Int -> Int -> Ptr a
-        -> Int -> Ptr a -> Int -> IO ()
-  tpsv  :: Order -> Uplo -> Transpose -> Diag -> Int -> Ptr a -> Ptr a
-        -> Int -> IO ()
-  hemv  :: Order -> Uplo -> Int -> a -> Ptr a -> Int -> Ptr a -> Int
-        -> a -> Ptr a -> Int -> IO ()
-  hbmv  :: Order -> Uplo -> Int -> Int -> a -> Ptr a -> Int -> Ptr a
-        -> Int -> a -> Ptr a -> Int -> IO ()
-  hpmv  :: Order -> Uplo -> Int -> a -> Ptr a -> Ptr a -> Int -> a
-        -> Ptr a -> Int -> IO ()
-  geru  :: Order -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int
-        -> Ptr a -> Int -> IO ()
-  gerc  :: Order -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int
-        -> Ptr a -> Int -> IO ()
-  her   :: Order -> Uplo -> Int -> RealType a -> Ptr a -> Int
-        -> Ptr a -> Int -> IO ()
-  hpr   :: Order -> Uplo -> Int -> RealType a -> Ptr a -> Int
-        -> Ptr a -> IO ()
-  her2  :: Order -> Uplo -> Int -> a -> Ptr a -> Int -> Ptr a -> Int
-        -> Ptr a -> Int -> IO ()
-  hpr2  :: Order -> Uplo -> Int -> a -> Ptr a -> Int -> Ptr a -> Int
-        -> Ptr a -> IO ()
-
-  -- | Calculate a general matrix-matrix product:
-  --
-  --   > c := alpha * opa(a) * opb(b) + beta * c
-  --
-  --   where `opa` and `opb` are operations specified by @transa@ and
-  --   @transb@ respectively.
-  gemm  :: Order     -- ^ Layout of all matrices.
-        -> Transpose -- ^ (@transa@) Operation applied to @a@.
-        -> Transpose -- ^ (@transb@) Operation applied to @b@.
-        -> Int       -- ^ (@m@) Number of rows of @op(a)@ and @c@.
-        -> Int       -- ^ (@n@) Number of columns of @op(b)@ and @c@.
-        -> Int       -- ^ (@k@) Number of columns of @op(a)@ and
-                     --         number of of rows of @op(b)@.
-        -> a         -- ^ (@alpha@) Scaling factor of the product.
-        -> Ptr a     -- ^ (@a@) Pointer to a matrix.
-        -> Int       -- ^ (@lda@) Stride of the major dimension of @a@.
-        -> Ptr a     -- ^ (@b@) Pointer to a matrix.
-        -> Int       -- ^ (@ldb@) Stride of the major dimension of @b@.
-        -> a         -- ^ (@beta@) Scaling factor of the original @c@.
-        -> Ptr a     -- ^ (@c@) Pointer to a mutable matrix.
-        -> Int       -- ^ (@ldc@) Stride of the major dimension of @c@.
-        -> IO ()
-
-  symm  :: Order -> Side -> Uplo -> Int -> Int -> a -> Ptr a -> Int
-        -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()
-  syrk  :: Order -> Uplo -> Transpose -> Int -> Int -> a -> Ptr a -> Int
-        -> a -> Ptr a -> Int -> IO ()
-  syr2k :: Order -> Uplo -> Transpose -> Int -> Int -> a -> Ptr a -> Int
-        -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()
-  hemm  :: Order -> Side -> Uplo -> Int -> Int -> a -> Ptr a -> Int
-        -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()
-  herk  :: Order -> Uplo -> Transpose -> Int -> Int -> RealType a -> Ptr a
-        -> Int -> RealType a -> Ptr a -> Int -> IO ()
-  her2k :: Order -> Uplo -> Transpose -> Int -> Int -> a -> Ptr a -> Int
-        -> Ptr a -> Int -> RealType a -> Ptr a -> Int -> IO ()
-  trmm  :: Order -> Side -> Uplo -> Transpose -> Diag -> Int -> Int
-        -> a -> Ptr a -> Int -> Ptr a -> Int -> IO ()
-  trsm  :: Order -> Side -> Uplo -> Transpose -> Diag -> Int -> Int
-        -> a -> Ptr a -> Int -> Ptr a -> Int -> IO ()
-
--- | Blas operations that are only applicable to real numbers.
---
---   Note: although complex versions of 'rot' and 'rotg' exist in many
---   implementations, they are not part of the official Blas standard and
---   therefore not included here.  If you /really/ need them, submit a ticket
---   so we can try to come up with a solution.
-class Numeric a => RealNumeric a where
-  rotg  :: Ptr a -> Ptr a -> Ptr a -> Ptr a -> IO ()
-  rotmg :: Ptr a -> Ptr a -> Ptr a -> a -> Ptr a -> IO ()
-  rot   :: Int -> Ptr a -> Int -> Ptr a -> Int -> a -> a -> IO ()
-  rotm  :: Int -> Ptr a -> Int -> Ptr a -> Int -> Ptr a -> IO ()
-
-instance Numeric Float where
-  type RealType Float = Float
-  dotu  = C.sdot
-  dotc  = C.sdot
-  nrm2  = C.snrm2
-  asum  = C.sasum
-  iamax = C.isamax
-  swap  = C.sswap
-  copy  = C.scopy
-  axpy  = C.saxpy
-  scal  = C.sscal
-  gemv  = C.sgemv
-  gbmv  = C.sgbmv
-  trmv  = C.strmv
-  tbmv  = C.stbmv
-  tpmv  = C.stpmv
-  trsv  = C.strsv
-  tbsv  = C.stbsv
-  tpsv  = C.stpsv
-  hemv  = C.ssymv
-  hbmv  = C.ssbmv
-  hpmv  = C.sspmv
-  geru  = C.sger
-  gerc  = C.sger
-  her   = C.ssyr
-  hpr   = C.sspr
-  her2  = C.ssyr2
-  hpr2  = C.sspr2
-  gemm  = C.sgemm
-  symm  = C.ssymm
-  hemm  = C.ssymm
-  syrk  = C.ssyrk
-  herk  = C.ssyrk
-  syr2k = C.ssyr2k
-  her2k = C.ssyr2k
-  trmm  = C.strmm
-  trsm  = C.strsm
-
-instance RealNumeric Float where
-  rotg  = C.srotg
-  rotmg = C.srotmg
-  rot   = C.srot
-  rotm  = C.srotm
-
-instance Numeric Double where
-  type RealType Double = Double
-  dotu  = C.ddot
-  dotc  = C.ddot
-  nrm2  = C.dnrm2
-  asum  = C.dasum
-  iamax = C.idamax
-  swap  = C.dswap
-  copy  = C.dcopy
-  axpy  = C.daxpy
-  scal  = C.dscal
-  gemv  = C.dgemv
-  gbmv  = C.dgbmv
-  trmv  = C.dtrmv
-  tbmv  = C.dtbmv
-  tpmv  = C.dtpmv
-  trsv  = C.dtrsv
-  tbsv  = C.dtbsv
-  tpsv  = C.dtpsv
-  hemv  = C.dsymv
-  hbmv  = C.dsbmv
-  hpmv  = C.dspmv
-  geru  = C.dger
-  gerc  = C.dger
-  her   = C.dsyr
-  hpr   = C.dspr
-  her2  = C.dsyr2
-  hpr2  = C.dspr2
-  gemm  = C.dgemm
-  symm  = C.dsymm
-  hemm  = C.dsymm
-  syrk  = C.dsyrk
-  herk  = C.dsyrk
-  syr2k = C.dsyr2k
-  her2k = C.dsyr2k
-  trmm  = C.dtrmm
-  trsm  = C.dtrsm
-
-instance RealNumeric Double where
-  rotg  = C.drotg
-  rotmg = C.drotmg
-  rot   = C.drot
-  rotm  = C.drotm
-
-instance Numeric (Complex Float) where
-  type RealType (Complex Float) = Float
-  dotu a b c d e = getReturnValue (C.cdotu_sub a b c d e)
-  dotc a b c d e = getReturnValue (C.cdotc_sub a b c d e)
-  nrm2  = C.scnrm2
-  asum  = C.scasum
-  iamax = C.icamax
-  swap  = C.cswap
-  copy  = C.ccopy
-  axpy  = C.caxpy
-  scal n (alpha :+ 0) = C.csscal n alpha
-  scal n  alpha       = C.cscal  n alpha
-  gemv  = C.cgemv
-  gbmv  = C.cgbmv
-  trmv  = C.ctrmv
-  tbmv  = C.ctbmv
-  tpmv  = C.ctpmv
-  trsv  = C.ctrsv
-  tbsv  = C.ctbsv
-  tpsv  = C.ctpsv
-  hemv  = C.chemv
-  hbmv  = C.chbmv
-  hpmv  = C.chpmv
-  geru  = C.cgeru
-  gerc  = C.cgerc
-  her   = C.cher
-  hpr   = C.chpr
-  her2  = C.cher2
-  hpr2  = C.chpr2
-  gemm  = C.cgemm
-  symm  = C.csymm
-  hemm  = C.chemm
-  syrk  = C.csyrk
-  herk  = C.cherk
-  syr2k = C.csyr2k
-  her2k = C.cher2k
-  trmm  = C.ctrmm
-  trsm  = C.ctrsm
-
-instance Numeric (Complex Double) where
-  type RealType (Complex Double) = Double
-  dotu a b c d e = getReturnValue (C.zdotu_sub a b c d e)
-  dotc a b c d e = getReturnValue (C.zdotc_sub a b c d e)
-  nrm2  = C.dznrm2
-  asum  = C.dzasum
-  iamax = C.izamax
-  swap  = C.zswap
-  copy  = C.zcopy
-  axpy  = C.zaxpy
-  scal n (alpha :+ 0) = C.zdscal n alpha
-  scal n  alpha       = C.zscal  n alpha
-  gemv  = C.zgemv
-  gbmv  = C.zgbmv
-  trmv  = C.ztrmv
-  tbmv  = C.ztbmv
-  tpmv  = C.ztpmv
-  trsv  = C.ztrsv
-  tbsv  = C.ztbsv
-  tpsv  = C.ztpsv
-  hemv  = C.zhemv
-  hbmv  = C.zhbmv
-  hpmv  = C.zhpmv
-  geru  = C.zgeru
-  gerc  = C.zgerc
-  her   = C.zher
-  hpr   = C.zhpr
-  her2  = C.zher2
-  hpr2  = C.zhpr2
-  gemm  = C.zgemm
-  symm  = C.zsymm
-  hemm  = C.zhemm
-  syrk  = C.zsyrk
-  herk  = C.zherk
-  syr2k = C.zsyr2k
-  her2k = C.zher2k
-  trmm  = C.ztrmm
-  trsm  = C.ztrsm
+-- This file is auto-generated.  Do not edit directly.
+-- |
+--   Stability: Experimental
+--
+--   Generic interface to Blas using unsafe foreign calls.  Refer to the GHC
+--   documentation for more information regarding appropriate use of safe and unsafe
+--   foreign calls.
+--
+--   The functions here are named in a similar fashion to the original Blas interface, with
+--   the type-dependent letter(s) removed.  Some functions have been merged with
+--   others to allow the interface to work on both real and complex numbers.  If you can't a
+--   particular function, try looking for its corresponding complex equivalent (e.g.
+--   @symv@ is a special case of 'hemv' applied to real numbers).
+--
+--   Note: although complex versions of 'rot' and 'rotg' exist in many implementations,
+--   they are not part of the official Blas standard and therefore not included here.  If
+--   you /really/ need them, submit a ticket so we can try to come up with a solution.
+--
+--   The documentation here is still incomplete.  Consult the
+--   <http://netlib.org/blas/#_blas_routines official documentation> for more
+--   information.
+--
+--   Notation:
+--
+--     * @⋅@ denotes dot product (without any conjugation).
+--     * @*@ denotes complex conjugation.
+--     * @⊤@ denotes transpose.
+--     * @†@ denotes conjugate transpose (Hermitian conjugate).
+--
+--   Conventions:
+--
+--     * All scalars are denoted with lowercase Greek letters
+--     * All vectors are denoted with lowercase Latin letters and are
+--       assumed to be column vectors (unless transposed).
+--     * All matrices are denoted with uppercase Latin letters.
+{-# LANGUAGE FlexibleInstances, TypeFamilies #-}
+module Blas.Generic.Unsafe (
+    Numeric(..)
+  , RealNumeric(..)
+  , D.dsdot
+  , S.sdsdot
+  ) where
+import Data.Complex (Complex)
+import Foreign (Ptr, Storable)
+import Blas.Primitive.Types (Order, Transpose, Uplo, Diag, Side)
+import qualified Blas.Specialized.Float.Unsafe as S
+import qualified Blas.Specialized.Double.Unsafe as D
+import qualified Blas.Specialized.ComplexFloat.Unsafe as C
+import qualified Blas.Specialized.ComplexDouble.Unsafe as Z
+
+-- | Blas operations that are applicable to real and complex numbers.
+--
+--   Instances are defined for the 4 types supported by Blas: the single- and
+--   double-precision floating point types and their complex versions.
+class (Floating a, Storable a) => Numeric a where
+
+  -- | The corresponding real type of @a@.
+  --
+  --   In other words, @'RealType' ('Complex' a)@ is an alias for @a@.  For everything
+  --   else, @'RealType' a@ is simply @a@.
+  type RealType a :: *
+  -- | Swap two vectors:
+  --
+  --   > (x, y) ← (y, x)
+  swap :: Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply a vector by a scalar.
+  --
+  --   > x ← α x
+  scal :: Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Copy a vector into another vector:
+  --
+  --   > y ← x
+  copy :: Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Add a scalar-vector product to a vector.
+  --
+  --   > y ← α x + y
+  axpy :: Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Calculate the bilinear dot product of two vectors:
+  --
+  --   > x ⋅ y ≡ ∑[i] x[i] y[i]
+  dotu :: Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO a
+
+  -- | Calculate the sesquilinear dot product of two vectors.
+  --
+  --   > x* ⋅ y ≡ ∑[i] x[i]* y[i]
+  dotc :: Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO a
+
+  -- | Calculate the Euclidean (L²) norm of a vector:
+  --
+  --   > ‖x‖₂ ≡ √(∑[i] x[i]²)
+  nrm2 :: Int
+       -> Ptr a
+       -> Int
+       -> IO (RealType a)
+
+  -- | Calculate the Manhattan (L¹) norm, equal to the sum of the magnitudes of the elements:
+  --
+  --   > ‖x‖₁ = ∑[i] |x[i]|
+  asum :: Int
+       -> Ptr a
+       -> Int
+       -> IO (RealType a)
+
+  -- | Calculate the index of the element with the maximum magnitude (absolute value).
+  iamax :: Int
+        -> Ptr a
+        -> Int
+        -> IO Int
+
+  -- | Perform a general matrix-vector update.
+  --
+  --   > y ← α T(A) x + β y
+  gemv :: Order
+       -> Transpose
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a general banded matrix-vector update.
+  --
+  --   > y ← α T(A) x + β y
+  gbmv :: Order
+       -> Transpose
+       -> Int
+       -> Int
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a hermitian matrix-vector update.
+  --
+  --   > y ← α A x + β y
+  hemv :: Order
+       -> Uplo
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a hermitian banded matrix-vector update.
+  --
+  --   > y ← α A x + β y
+  hbmv :: Order
+       -> Uplo
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a hermitian packed matrix-vector update.
+  --
+  --   > y ← α A x + β y
+  hpmv :: Order
+       -> Uplo
+       -> Int
+       -> a
+       -> Ptr a
+       -> Ptr a
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply a triangular matrix by a vector.
+  --
+  --   > x ← T(A) x
+  trmv :: Order
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply a triangular banded matrix by a vector.
+  --
+  --   > x ← T(A) x
+  tbmv :: Order
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply a triangular packed matrix by a vector.
+  --
+  --   > x ← T(A) x
+  tpmv :: Order
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Ptr a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply an inverse triangular matrix by a vector.
+  --
+  --   > x ← T(A⁻¹) x
+  trsv :: Order
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply an inverse triangular banded matrix by a vector.
+  --
+  --   > x ← T(A⁻¹) x
+  tbsv :: Order
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Multiply an inverse triangular packed matrix by a vector.
+  --
+  --   > x ← T(A⁻¹) x
+  tpsv :: Order
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Ptr a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform an unconjugated rank-1 update of a general matrix.
+  --
+  --   > A ← α x y⊤ + A
+  geru :: Order
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a conjugated rank-1 update of a general matrix.
+  --
+  --   > A ← α x y† + A
+  gerc :: Order
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a rank-1 update of a Hermitian matrix.
+  --
+  --   > A ← α x y† + A
+  her :: Order
+      -> Uplo
+      -> Int
+      -> RealType a
+      -> Ptr a
+      -> Int
+      -> Ptr a
+      -> Int
+      -> IO ()
+
+  -- | Perform a rank-1 update of a Hermitian packed matrix.
+  --
+  --   > A ← α x y† + A
+  hpr :: Order
+      -> Uplo
+      -> Int
+      -> RealType a
+      -> Ptr a
+      -> Int
+      -> Ptr a
+      -> IO ()
+
+  -- | Perform a rank-2 update of a Hermitian matrix.
+  --
+  --   > A ← α x y† + y (α x)† + A
+  her2 :: Order
+       -> Uplo
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a rank-2 update of a Hermitian packed matrix.
+  --
+  --   > A ← α x y† + y (α x)† + A
+  hpr2 :: Order
+       -> Uplo
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> IO ()
+
+  -- | Perform a general matrix-matrix update.
+  --
+  --   > C ← α T(A) U(B) + β C
+  gemm :: Order -- ^ Layout of all the matrices.
+       -> Transpose -- ^ The operation @T@ to be applied to @A@.
+       -> Transpose -- ^ The operation @U@ to be applied to @B@.
+       -> Int -- ^ Number of rows of @T(A)@ and @C@.
+       -> Int -- ^ Number of columns of @U(B)@ and @C@.
+       -> Int -- ^ Number of columns of @T(A)@ and number of rows of @U(B)@.
+       -> a -- ^ Scaling factor @α@ of the product.
+       -> Ptr a -- ^ Pointer to a matrix @A@.
+       -> Int -- ^ Stride of the major dimension of @A@.
+       -> Ptr a -- ^ Pointer to a matrix @B@.
+       -> Int -- ^ Stride of the major dimension of @B@.
+       -> a -- ^ Scaling factor @β@ of the original @C@.
+       -> Ptr a -- ^ Pointer to a mutable matrix @C@.
+       -> Int -- ^ Stride of the major dimension of @C@.
+       -> IO ()
+
+  -- | Perform a symmetric matrix-matrix update.
+  --
+  --   > C ← α A B + β C    or    C ← α B A + β C
+  --
+  --   where @A@ is symmetric.  The matrix @A@ must be in an unpacked format, although the
+  --   routine will only access half of it as specified by the @'Uplo'@ argument.
+  symm :: Order -- ^ Layout of all the matrices.
+       -> Side -- ^ Side that @A@ appears in the product.
+       -> Uplo -- ^ The part of @A@ that is used.
+       -> Int -- ^ Number of rows of @C@.
+       -> Int -- ^ Number of columns of @C@.
+       -> a -- ^ Scaling factor @α@ of the product.
+       -> Ptr a -- ^ Pointer to a symmetric matrix @A@.
+       -> Int -- ^ Stride of the major dimension of @A@.
+       -> Ptr a -- ^ Pointer to a matrix @B@.
+       -> Int -- ^ Stride of the major dimension of @B@.
+       -> a -- ^ Scaling factor @α@ of the original @C@.
+       -> Ptr a -- ^ Pointer to a mutable matrix @C@.
+       -> Int -- ^ Stride of the major dimension of @C@.
+       -> IO ()
+
+  -- | Perform a Hermitian matrix-matrix update.
+  --
+  --   > C ← α A B + β C    or    C ← α B A + β C
+  --
+  --   where @A@ is Hermitian.  The matrix @A@ must be in an unpacked format, although the
+  --   routine will only access half of it as specified by the @'Uplo'@ argument.
+  hemm :: Order -- ^ Layout of all the matrices.
+       -> Side -- ^ Side that @A@ appears in the product.
+       -> Uplo -- ^ The part of @A@ that is used.
+       -> Int -- ^ Number of rows of @C@.
+       -> Int -- ^ Number of columns of @C@.
+       -> a -- ^ Scaling factor @α@ of the product.
+       -> Ptr a -- ^ Pointer to a Hermitian matrix @A@.
+       -> Int -- ^ Stride of the major dimension of @A@.
+       -> Ptr a -- ^ Pointer to a matrix @B@.
+       -> Int -- ^ Stride of the major dimension of @B@.
+       -> a -- ^ Scaling factor @α@ of the original @C@.
+       -> Ptr a -- ^ Pointer to a mutable matrix @C@.
+       -> Int -- ^ Stride of the major dimension of @C@.
+       -> IO ()
+
+  -- | Perform a symmetric rank-k update.
+  --
+  --   > C ← α A A⊤ + β C    or    C ← α A⊤ A + β C
+  syrk :: Order
+       -> Uplo
+       -> Transpose
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a Hermitian rank-k update.
+  --
+  --   > C ← α A A† + β C    or    C ← α A† A + β C
+  herk :: Order
+       -> Uplo
+       -> Transpose
+       -> Int
+       -> Int
+       -> RealType a
+       -> Ptr a
+       -> Int
+       -> RealType a
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform a symmetric rank-2k update.
+  --
+  --   > C ← α A B⊤ + α* B A⊤ + β C    or    C ← α A⊤ B + α* B⊤ A + β C
+  syr2k :: Order
+        -> Uplo
+        -> Transpose
+        -> Int
+        -> Int
+        -> a
+        -> Ptr a
+        -> Int
+        -> Ptr a
+        -> Int
+        -> a
+        -> Ptr a
+        -> Int
+        -> IO ()
+
+  -- | Perform a Hermitian rank-2k update.
+  --
+  --   > C ← α A B† + α* B A† + β C    or    C ← α A† B + α* B† A + β C
+  her2k :: Order
+        -> Uplo
+        -> Transpose
+        -> Int
+        -> Int
+        -> a
+        -> Ptr a
+        -> Int
+        -> Ptr a
+        -> Int
+        -> RealType a
+        -> Ptr a
+        -> Int
+        -> IO ()
+
+  -- | Perform a triangular matrix-matrix multiplication.
+  --
+  --   > B ← α T(A) B    or    B ← α B T(A)
+  --
+  --   where @A@ is triangular.
+  trmm :: Order
+       -> Side
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+  -- | Perform an inverse triangular matrix-matrix multiplication.
+  --
+  --   > B ← α T(A⁻¹) B    or    B ← α B T(A⁻¹)
+  --
+  --   where @A@ is triangular.
+  trsm :: Order
+       -> Side
+       -> Uplo
+       -> Transpose
+       -> Diag
+       -> Int
+       -> Int
+       -> a
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> IO ()
+
+-- | Blas operations that are only applicable to real numbers.
+class Numeric a => RealNumeric a where
+
+  -- | Generate a Givens rotation. (Only available for real floating-point types.)
+  rotg :: Ptr a
+       -> Ptr a
+       -> Ptr a
+       -> Ptr a
+       -> IO ()
+
+  -- | Generate a modified Givens rotation. (Only available for real floating-point
+  --   types.)
+  rotmg :: Ptr a
+        -> Ptr a
+        -> Ptr a
+        -> a
+        -> Ptr a
+        -> IO ()
+
+  -- | Apply a Givens rotation. (Only available for real floating-point types.)
+  rot :: Int
+      -> Ptr a
+      -> Int
+      -> Ptr a
+      -> Int
+      -> a
+      -> a
+      -> IO ()
+
+  -- | Apply a modified Givens rotation. (Only available for real floating-point types.)
+  rotm :: Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> Int
+       -> Ptr a
+       -> IO ()
+
+instance Numeric Float where
+  type RealType Float = Float
+  swap = S.swap
+  scal = S.scal
+  copy = S.copy
+  axpy = S.axpy
+  dotu = S.dotu
+  dotc = S.dotc
+  nrm2 = S.nrm2
+  asum = S.asum
+  iamax = S.iamax
+  gemv = S.gemv
+  gbmv = S.gbmv
+  hemv = S.hemv
+  hbmv = S.hbmv
+  hpmv = S.hpmv
+  trmv = S.trmv
+  tbmv = S.tbmv
+  tpmv = S.tpmv
+  trsv = S.trsv
+  tbsv = S.tbsv
+  tpsv = S.tpsv
+  geru = S.geru
+  gerc = S.gerc
+  her = S.her
+  hpr = S.hpr
+  her2 = S.her2
+  hpr2 = S.hpr2
+  gemm = S.gemm
+  symm = S.symm
+  hemm = S.hemm
+  syrk = S.syrk
+  herk = S.herk
+  syr2k = S.syr2k
+  her2k = S.her2k
+  trmm = S.trmm
+  trsm = S.trsm
+
+
+instance Numeric Double where
+  type RealType Double = Double
+  swap = D.swap
+  scal = D.scal
+  copy = D.copy
+  axpy = D.axpy
+  dotu = D.dotu
+  dotc = D.dotc
+  nrm2 = D.nrm2
+  asum = D.asum
+  iamax = D.iamax
+  gemv = D.gemv
+  gbmv = D.gbmv
+  hemv = D.hemv
+  hbmv = D.hbmv
+  hpmv = D.hpmv
+  trmv = D.trmv
+  tbmv = D.tbmv
+  tpmv = D.tpmv
+  trsv = D.trsv
+  tbsv = D.tbsv
+  tpsv = D.tpsv
+  geru = D.geru
+  gerc = D.gerc
+  her = D.her
+  hpr = D.hpr
+  her2 = D.her2
+  hpr2 = D.hpr2
+  gemm = D.gemm
+  symm = D.symm
+  hemm = D.hemm
+  syrk = D.syrk
+  herk = D.herk
+  syr2k = D.syr2k
+  her2k = D.her2k
+  trmm = D.trmm
+  trsm = D.trsm
+
+
+instance Numeric (Complex Float) where
+  type RealType (Complex Float) = Float
+  swap = C.swap
+  scal = C.scal
+  copy = C.copy
+  axpy = C.axpy
+  dotu = C.dotu
+  dotc = C.dotc
+  nrm2 = C.nrm2
+  asum = C.asum
+  iamax = C.iamax
+  gemv = C.gemv
+  gbmv = C.gbmv
+  hemv = C.hemv
+  hbmv = C.hbmv
+  hpmv = C.hpmv
+  trmv = C.trmv
+  tbmv = C.tbmv
+  tpmv = C.tpmv
+  trsv = C.trsv
+  tbsv = C.tbsv
+  tpsv = C.tpsv
+  geru = C.geru
+  gerc = C.gerc
+  her = C.her
+  hpr = C.hpr
+  her2 = C.her2
+  hpr2 = C.hpr2
+  gemm = C.gemm
+  symm = C.symm
+  hemm = C.hemm
+  syrk = C.syrk
+  herk = C.herk
+  syr2k = C.syr2k
+  her2k = C.her2k
+  trmm = C.trmm
+  trsm = C.trsm
+
+
+instance Numeric (Complex Double) where
+  type RealType (Complex Double) = Double
+  swap = Z.swap
+  scal = Z.scal
+  copy = Z.copy
+  axpy = Z.axpy
+  dotu = Z.dotu
+  dotc = Z.dotc
+  nrm2 = Z.nrm2
+  asum = Z.asum
+  iamax = Z.iamax
+  gemv = Z.gemv
+  gbmv = Z.gbmv
+  hemv = Z.hemv
+  hbmv = Z.hbmv
+  hpmv = Z.hpmv
+  trmv = Z.trmv
+  tbmv = Z.tbmv
+  tpmv = Z.tpmv
+  trsv = Z.trsv
+  tbsv = Z.tbsv
+  tpsv = Z.tpsv
+  geru = Z.geru
+  gerc = Z.gerc
+  her = Z.her
+  hpr = Z.hpr
+  her2 = Z.her2
+  hpr2 = Z.hpr2
+  gemm = Z.gemm
+  symm = Z.symm
+  hemm = Z.hemm
+  syrk = Z.syrk
+  herk = Z.herk
+  syr2k = Z.syr2k
+  her2k = Z.her2k
+  trmm = Z.trmm
+  trsm = Z.trsm
+instance RealNumeric Float where
+  rotg = S.rotg
+  rotmg = S.rotmg
+  rot = S.rot
+  rotm = S.rotm
+
+
+instance RealNumeric Double where
+  rotg = D.rotg
+  rotmg = D.rotmg
+  rot = D.rot
+  rotm = D.rotm
diff --git a/src/Blas/Primitive/Safe.hs b/src/Blas/Primitive/Safe.hs
--- a/src/Blas/Primitive/Safe.hs
+++ b/src/Blas/Primitive/Safe.hs
@@ -1,19 +1,16 @@
--- GENERATED by C->Haskell Compiler, version 0.17.2 Crystal Seed, 24 Jan 2009 (Haskell)
+-- GENERATED by C->Haskell Compiler, version 0.20.1 The shapeless maps, 31 Oct 2014 (Haskell)
 -- Edit the ORIGNAL .chs file instead!
 
 
 {-# LINE 1 "src/Blas/Primitive/Safe_.chs" #-}
-{- This file is auto-generated.  Do not edit directly. -}
+-- This file is auto-generated.  Do not edit directly.
+-- |
+--   Stability: Stable
+--
+--   Foreign function interface to Blas.  These functions use safe foreign
+--   calls.  Refer to the GHC documentation for more information regarding appropriate
+--   use of safe and unsafe foreign calls.
 {-# LANGUAGE ForeignFunctionInterface #-}
-{-|
-
-Stability: stable
-
-Foreign function interface to Blas.  These functions use safe
-foreign calls.  Refer to the GHC documentation for more information regarding
-appropriate use of safe and unsafe foreign calls.
-
--}
 module Blas.Primitive.Safe (sdsdot, dsdot, sdot, ddot, cdotu_sub, zdotu_sub, cdotc_sub, zdotc_sub, snrm2, dnrm2, scnrm2, dznrm2, sasum, dasum, scasum, dzasum, isamax, idamax, icamax, izamax, sswap, dswap, cswap, zswap, scopy, dcopy, ccopy, zcopy, saxpy, daxpy, caxpy, zaxpy, srotg, drotg, srotmg, drotmg, srot, drot, srotm, drotm, sscal, dscal, cscal, csscal, zscal, zdscal, sgemv, dgemv, cgemv, zgemv, sgbmv, dgbmv, cgbmv, zgbmv, strmv, dtrmv, ctrmv, ztrmv, stbmv, dtbmv, ctbmv, ztbmv, stpmv, dtpmv, ctpmv, ztpmv, strsv, dtrsv, ctrsv, ztrsv, stbsv, dtbsv, ctbsv, ztbsv, stpsv, dtpsv, ctpsv, ztpsv, ssymv, dsymv, ssbmv, dsbmv, sspmv, dspmv, sger, dger, ssyr, dsyr, ssyr2, dsyr2, sspr, dspr, sspr2, dspr2, chemv, zhemv, chbmv, zhbmv, chpmv, zhpmv, cgeru, zgeru, cgerc, zgerc, cher, zher, chpr, zhpr, cher2, zher2, chpr2, zhpr2, sgemm, dgemm, cgemm, zgemm, ssymm, dsymm, csymm, zsymm, ssyrk, dsyrk, csyrk, zsyrk, ssyr2k, dsyr2k, csyr2k, zsyr2k, chemm, zhemm, cherk, zherk, cher2k, zher2k, strmm, dtrmm, ctrmm, ztrmm, strsm, dtrsm, ctrsm, ztrsm) where
 import Prelude hiding (Either(Left, Right))
 import Data.Complex (Complex)
@@ -38,7 +35,7 @@
   let {res' = fromCFloat res} in
   return (res')
 
-{-# LINE 24 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 21 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dsdot :: (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ((Double))
@@ -52,7 +49,7 @@
   let {res' = fromCDouble res} in
   return (res')
 
-{-# LINE 26 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 23 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 sdot :: (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ((Float))
@@ -66,7 +63,7 @@
   let {res' = fromCFloat res} in
   return (res')
 
-{-# LINE 28 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 25 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ddot :: (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ((Double))
@@ -80,7 +77,7 @@
   let {res' = fromCDouble res} in
   return (res')
 
-{-# LINE 30 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 27 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cdotu_sub :: (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> IO ()
@@ -94,7 +91,7 @@
   cdotu_sub'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 32 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 29 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zdotu_sub :: (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> IO ()
@@ -108,7 +105,7 @@
   zdotu_sub'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 34 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 31 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cdotc_sub :: (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> IO ()
@@ -122,7 +119,7 @@
   cdotc_sub'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 36 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 33 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zdotc_sub :: (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> IO ()
@@ -136,7 +133,7 @@
   zdotc_sub'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 38 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 35 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 snrm2 :: (Int) -> (Ptr Float) -> (Int) -> IO ((Float))
@@ -148,7 +145,7 @@
   let {res' = fromCFloat res} in
   return (res')
 
-{-# LINE 40 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 37 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dnrm2 :: (Int) -> (Ptr Double) -> (Int) -> IO ((Double))
@@ -160,7 +157,7 @@
   let {res' = fromCDouble res} in
   return (res')
 
-{-# LINE 42 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 39 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 scnrm2 :: (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ((Float))
@@ -172,7 +169,7 @@
   let {res' = fromCFloat res} in
   return (res')
 
-{-# LINE 44 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 41 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dznrm2 :: (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ((Double))
@@ -184,7 +181,7 @@
   let {res' = fromCDouble res} in
   return (res')
 
-{-# LINE 46 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 43 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 sasum :: (Int) -> (Ptr Float) -> (Int) -> IO ((Float))
@@ -196,7 +193,7 @@
   let {res' = fromCFloat res} in
   return (res')
 
-{-# LINE 48 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 45 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dasum :: (Int) -> (Ptr Double) -> (Int) -> IO ((Double))
@@ -208,7 +205,7 @@
   let {res' = fromCDouble res} in
   return (res')
 
-{-# LINE 50 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 47 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 scasum :: (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ((Float))
@@ -220,7 +217,7 @@
   let {res' = fromCFloat res} in
   return (res')
 
-{-# LINE 52 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 49 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dzasum :: (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ((Double))
@@ -232,7 +229,7 @@
   let {res' = fromCDouble res} in
   return (res')
 
-{-# LINE 54 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 51 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 isamax :: (Int) -> (Ptr Float) -> (Int) -> IO ((Int))
@@ -244,7 +241,7 @@
   let {res' = fromIntegral res} in
   return (res')
 
-{-# LINE 56 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 53 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 idamax :: (Int) -> (Ptr Double) -> (Int) -> IO ((Int))
@@ -256,7 +253,7 @@
   let {res' = fromIntegral res} in
   return (res')
 
-{-# LINE 58 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 55 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 icamax :: (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ((Int))
@@ -268,7 +265,7 @@
   let {res' = fromIntegral res} in
   return (res')
 
-{-# LINE 60 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 57 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 izamax :: (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ((Int))
@@ -280,7 +277,7 @@
   let {res' = fromIntegral res} in
   return (res')
 
-{-# LINE 62 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 59 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 sswap :: (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -293,7 +290,7 @@
   sswap'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 64 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 61 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dswap :: (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -306,7 +303,7 @@
   dswap'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 66 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 63 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cswap :: (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -319,7 +316,7 @@
   cswap'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 68 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 65 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zswap :: (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -332,7 +329,7 @@
   zswap'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 70 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 67 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 scopy :: (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -345,7 +342,7 @@
   scopy'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 72 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 69 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dcopy :: (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -358,7 +355,7 @@
   dcopy'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 74 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 71 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ccopy :: (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -371,7 +368,7 @@
   ccopy'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 76 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 73 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zcopy :: (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -384,7 +381,7 @@
   zcopy'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 78 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 75 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 saxpy :: (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -398,7 +395,7 @@
   saxpy'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 80 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 77 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 daxpy :: (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -412,7 +409,7 @@
   daxpy'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 82 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 79 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 caxpy :: (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -426,7 +423,7 @@
   caxpy'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 84 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 81 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zaxpy :: (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -440,7 +437,7 @@
   zaxpy'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 86 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 83 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 srotg :: (Ptr Float) -> (Ptr Float) -> (Ptr Float) -> (Ptr Float) -> IO ()
@@ -452,7 +449,7 @@
   srotg'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 88 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 85 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 drotg :: (Ptr Double) -> (Ptr Double) -> (Ptr Double) -> (Ptr Double) -> IO ()
@@ -464,7 +461,7 @@
   drotg'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 90 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 87 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 srotmg :: (Ptr Float) -> (Ptr Float) -> (Ptr Float) -> (Float) -> (Ptr Float) -> IO ()
@@ -477,7 +474,7 @@
   srotmg'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 92 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 89 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 drotmg :: (Ptr Double) -> (Ptr Double) -> (Ptr Double) -> (Double) -> (Ptr Double) -> IO ()
@@ -490,7 +487,7 @@
   drotmg'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 94 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 91 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 srot :: (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Float) -> IO ()
@@ -505,7 +502,7 @@
   srot'_ a1' a2' a3' a4' a5' a6' a7' >>
   return ()
 
-{-# LINE 96 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 93 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 drot :: (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Double) -> IO ()
@@ -520,7 +517,7 @@
   drot'_ a1' a2' a3' a4' a5' a6' a7' >>
   return ()
 
-{-# LINE 98 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 95 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 srotm :: (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> IO ()
@@ -534,7 +531,7 @@
   srotm'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 100 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 97 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 drotm :: (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> IO ()
@@ -548,7 +545,7 @@
   drotm'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 102 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 99 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 sscal :: (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -560,7 +557,7 @@
   sscal'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 104 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 101 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dscal :: (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -572,7 +569,7 @@
   dscal'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 106 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 103 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cscal :: (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -584,7 +581,7 @@
   cscal'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 108 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 105 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 csscal :: (Int) -> (Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -596,7 +593,7 @@
   csscal'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 110 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 107 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zscal :: (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -608,7 +605,7 @@
   zscal'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 112 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 109 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zdscal :: (Int) -> (Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -620,7 +617,7 @@
   zdscal'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 114 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 111 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 sgemv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -640,7 +637,7 @@
   sgemv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 116 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 113 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dgemv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -660,7 +657,7 @@
   dgemv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 118 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 115 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cgemv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -680,7 +677,7 @@
   cgemv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 120 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 117 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zgemv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -700,7 +697,7 @@
   zgemv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 122 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 119 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 sgbmv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -722,7 +719,7 @@
   sgbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 124 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 121 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dgbmv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -744,7 +741,7 @@
   dgbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 126 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 123 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cgbmv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -766,7 +763,7 @@
   cgbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 128 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 125 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zgbmv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -788,7 +785,7 @@
   zgbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 130 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 127 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 strmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -805,7 +802,7 @@
   strmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 132 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 129 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dtrmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -822,7 +819,7 @@
   dtrmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 134 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 131 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ctrmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -839,7 +836,7 @@
   ctrmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 136 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 133 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ztrmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -856,7 +853,7 @@
   ztrmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 138 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 135 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 stbmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -874,7 +871,7 @@
   stbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 140 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 137 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dtbmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -892,7 +889,7 @@
   dtbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 142 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 139 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ctbmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -910,7 +907,7 @@
   ctbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 144 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 141 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ztbmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -928,7 +925,7 @@
   ztbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 146 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 143 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 stpmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -944,7 +941,7 @@
   stpmv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 148 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 145 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dtpmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -960,7 +957,7 @@
   dtpmv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 150 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 147 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ctpmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Float)) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -976,7 +973,7 @@
   ctpmv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 152 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 149 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ztpmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Double)) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -992,7 +989,7 @@
   ztpmv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 154 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 151 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 strsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -1009,7 +1006,7 @@
   strsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 156 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 153 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dtrsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -1026,7 +1023,7 @@
   dtrsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 158 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 155 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ctrsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1043,7 +1040,7 @@
   ctrsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 160 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 157 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ztrsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1060,7 +1057,7 @@
   ztrsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 162 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 159 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 stbsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -1078,7 +1075,7 @@
   stbsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 164 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 161 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dtbsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -1096,7 +1093,7 @@
   dtbsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 166 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 163 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ctbsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1114,7 +1111,7 @@
   ctbsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 168 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 165 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ztbsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1132,7 +1129,7 @@
   ztbsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 170 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 167 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 stpsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1148,7 +1145,7 @@
   stpsv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 172 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 169 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dtpsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -1164,7 +1161,7 @@
   dtpsv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 174 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 171 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ctpsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Float)) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1180,7 +1177,7 @@
   ctpsv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 176 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 173 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ztpsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Double)) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1196,7 +1193,7 @@
   ztpsv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 178 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 175 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ssymv :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1215,7 +1212,7 @@
   ssymv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 180 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 177 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dsymv :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -1234,7 +1231,7 @@
   dsymv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 182 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 179 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ssbmv :: (Order) -> (Uplo) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1254,7 +1251,7 @@
   ssbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 184 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 181 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dsbmv :: (Order) -> (Uplo) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -1274,7 +1271,7 @@
   dsbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 186 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 183 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 sspmv :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr Float) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1292,7 +1289,7 @@
   sspmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 188 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 185 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dspmv :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr Double) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -1310,7 +1307,7 @@
   dspmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 190 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 187 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 sger :: (Order) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -1328,7 +1325,7 @@
   sger'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 192 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 189 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dger :: (Order) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -1346,7 +1343,7 @@
   dger'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 194 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 191 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ssyr :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -1362,7 +1359,7 @@
   ssyr'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 196 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 193 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dsyr :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -1378,7 +1375,7 @@
   dsyr'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 198 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 195 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ssyr2 :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -1396,7 +1393,7 @@
   ssyr2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 200 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 197 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dsyr2 :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -1414,7 +1411,7 @@
   dsyr2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 202 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 199 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 sspr :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> IO ()
@@ -1429,7 +1426,7 @@
   sspr'_ a1' a2' a3' a4' a5' a6' a7' >>
   return ()
 
-{-# LINE 204 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 201 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dspr :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> IO ()
@@ -1444,7 +1441,7 @@
   dspr'_ a1' a2' a3' a4' a5' a6' a7' >>
   return ()
 
-{-# LINE 206 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 203 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 sspr2 :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> IO ()
@@ -1461,7 +1458,7 @@
   sspr2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 208 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 205 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dspr2 :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> IO ()
@@ -1478,7 +1475,7 @@
   dspr2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 210 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 207 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 chemv :: (Order) -> (Uplo) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1497,7 +1494,7 @@
   chemv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 212 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 209 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zhemv :: (Order) -> (Uplo) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1516,7 +1513,7 @@
   zhemv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 214 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 211 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 chbmv :: (Order) -> (Uplo) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1536,7 +1533,7 @@
   chbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 216 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 213 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zhbmv :: (Order) -> (Uplo) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1556,7 +1553,7 @@
   zhbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 218 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 215 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 chpmv :: (Order) -> (Uplo) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1574,7 +1571,7 @@
   chpmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 220 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 217 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zhpmv :: (Order) -> (Uplo) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1592,7 +1589,7 @@
   zhpmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 222 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 219 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cgeru :: (Order) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1610,7 +1607,7 @@
   cgeru'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 224 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 221 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zgeru :: (Order) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1628,7 +1625,7 @@
   zgeru'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 226 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 223 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cgerc :: (Order) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1646,7 +1643,7 @@
   cgerc'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 228 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 225 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zgerc :: (Order) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1664,7 +1661,7 @@
   zgerc'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 230 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 227 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cher :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1680,7 +1677,7 @@
   cher'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 232 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 229 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zher :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1696,7 +1693,7 @@
   zher'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 234 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 231 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 chpr :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> IO ()
@@ -1711,7 +1708,7 @@
   chpr'_ a1' a2' a3' a4' a5' a6' a7' >>
   return ()
 
-{-# LINE 236 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 233 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zhpr :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> IO ()
@@ -1726,7 +1723,7 @@
   zhpr'_ a1' a2' a3' a4' a5' a6' a7' >>
   return ()
 
-{-# LINE 238 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 235 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cher2 :: (Order) -> (Uplo) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1744,7 +1741,7 @@
   cher2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 240 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 237 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zher2 :: (Order) -> (Uplo) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1762,7 +1759,7 @@
   zher2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 242 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 239 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 chpr2 :: (Order) -> (Uplo) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> IO ()
@@ -1779,7 +1776,7 @@
   chpr2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 244 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 241 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zhpr2 :: (Order) -> (Uplo) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> IO ()
@@ -1796,7 +1793,7 @@
   zhpr2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 246 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 243 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 sgemm :: (Order) -> (Transpose) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1818,7 +1815,7 @@
   sgemm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 248 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 245 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dgemm :: (Order) -> (Transpose) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -1840,7 +1837,7 @@
   dgemm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 250 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 247 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cgemm :: (Order) -> (Transpose) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1862,7 +1859,7 @@
   cgemm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 252 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 249 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zgemm :: (Order) -> (Transpose) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1884,7 +1881,7 @@
   zgemm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 254 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 251 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ssymm :: (Order) -> (Side) -> (Uplo) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1905,7 +1902,7 @@
   ssymm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 256 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 253 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dsymm :: (Order) -> (Side) -> (Uplo) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -1926,7 +1923,7 @@
   dsymm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 258 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 255 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 csymm :: (Order) -> (Side) -> (Uplo) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1947,7 +1944,7 @@
   csymm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 260 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 257 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zsymm :: (Order) -> (Side) -> (Uplo) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1968,7 +1965,7 @@
   zsymm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 262 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 259 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ssyrk :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1987,7 +1984,7 @@
   ssyrk'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 264 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 261 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dsyrk :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -2006,7 +2003,7 @@
   dsyrk'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 266 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 263 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 csyrk :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2025,7 +2022,7 @@
   csyrk'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 268 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 265 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zsyrk :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2044,7 +2041,7 @@
   zsyrk'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 270 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 267 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ssyr2k :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -2065,7 +2062,7 @@
   ssyr2k'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 272 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 269 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dsyr2k :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -2086,7 +2083,7 @@
   dsyr2k'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 274 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 271 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 csyr2k :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2107,7 +2104,7 @@
   csyr2k'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 276 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 273 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zsyr2k :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2128,7 +2125,7 @@
   zsyr2k'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 278 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 275 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 chemm :: (Order) -> (Side) -> (Uplo) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2149,7 +2146,7 @@
   chemm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 280 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 277 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zhemm :: (Order) -> (Side) -> (Uplo) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2170,7 +2167,7 @@
   zhemm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 282 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 279 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cherk :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Float) -> (Ptr (Complex Float)) -> (Int) -> (Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2189,7 +2186,7 @@
   cherk'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 284 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 281 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zherk :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Double) -> (Ptr (Complex Double)) -> (Int) -> (Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2208,7 +2205,7 @@
   zherk'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 286 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 283 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 cher2k :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2229,7 +2226,7 @@
   cher2k'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 288 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 285 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 zher2k :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2250,7 +2247,7 @@
   zher2k'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 290 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 287 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 strmm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -2270,7 +2267,7 @@
   strmm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 292 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 289 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dtrmm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -2290,7 +2287,7 @@
   dtrmm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 294 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 291 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ctrmm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2310,7 +2307,7 @@
   ctrmm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 296 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 293 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ztrmm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2330,7 +2327,7 @@
   ztrmm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 298 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 295 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 strsm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -2350,7 +2347,7 @@
   strsm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 300 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 297 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 dtrsm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -2370,7 +2367,7 @@
   dtrsm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 302 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 299 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ctrsm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2390,7 +2387,7 @@
   ctrsm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 304 "src/Blas/Primitive/Safe_.chs" #-}
+{-# LINE 301 "src/Blas/Primitive/Safe_.chs" #-}
 
 
 ztrsm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2410,8 +2407,7 @@
   ztrsm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 306 "src/Blas/Primitive/Safe_.chs" #-}
-
+{-# LINE 21 "src/Blas/Primitive/Safe_.chs" #-}
 
 foreign import ccall safe "src/Blas/Primitive/Safe_.chs.h cblas_sdsdot"
   sdsdot'_ :: (BlasInt -> (CFloat -> ((Ptr CFloat) -> (BlasInt -> ((Ptr CFloat) -> (BlasInt -> (IO CFloat)))))))
diff --git a/src/Blas/Primitive/Unsafe.hs b/src/Blas/Primitive/Unsafe.hs
--- a/src/Blas/Primitive/Unsafe.hs
+++ b/src/Blas/Primitive/Unsafe.hs
@@ -1,19 +1,16 @@
--- GENERATED by C->Haskell Compiler, version 0.17.2 Crystal Seed, 24 Jan 2009 (Haskell)
+-- GENERATED by C->Haskell Compiler, version 0.20.1 The shapeless maps, 31 Oct 2014 (Haskell)
 -- Edit the ORIGNAL .chs file instead!
 
 
 {-# LINE 1 "src/Blas/Primitive/Unsafe_.chs" #-}
-{- This file is auto-generated.  Do not edit directly. -}
+-- This file is auto-generated.  Do not edit directly.
+-- |
+--   Stability: Stable
+--
+--   Foreign function interface to Blas.  These functions use unsafe foreign
+--   calls.  Refer to the GHC documentation for more information regarding appropriate
+--   use of safe and unsafe foreign calls.
 {-# LANGUAGE ForeignFunctionInterface #-}
-{-|
-
-Stability: stable
-
-Foreign function interface to Blas.  These functions use unsafe
-foreign calls.  Refer to the GHC documentation for more information regarding
-appropriate use of safe and unsafe foreign calls.
-
--}
 module Blas.Primitive.Unsafe (sdsdot, dsdot, sdot, ddot, cdotu_sub, zdotu_sub, cdotc_sub, zdotc_sub, snrm2, dnrm2, scnrm2, dznrm2, sasum, dasum, scasum, dzasum, isamax, idamax, icamax, izamax, sswap, dswap, cswap, zswap, scopy, dcopy, ccopy, zcopy, saxpy, daxpy, caxpy, zaxpy, srotg, drotg, srotmg, drotmg, srot, drot, srotm, drotm, sscal, dscal, cscal, csscal, zscal, zdscal, sgemv, dgemv, cgemv, zgemv, sgbmv, dgbmv, cgbmv, zgbmv, strmv, dtrmv, ctrmv, ztrmv, stbmv, dtbmv, ctbmv, ztbmv, stpmv, dtpmv, ctpmv, ztpmv, strsv, dtrsv, ctrsv, ztrsv, stbsv, dtbsv, ctbsv, ztbsv, stpsv, dtpsv, ctpsv, ztpsv, ssymv, dsymv, ssbmv, dsbmv, sspmv, dspmv, sger, dger, ssyr, dsyr, ssyr2, dsyr2, sspr, dspr, sspr2, dspr2, chemv, zhemv, chbmv, zhbmv, chpmv, zhpmv, cgeru, zgeru, cgerc, zgerc, cher, zher, chpr, zhpr, cher2, zher2, chpr2, zhpr2, sgemm, dgemm, cgemm, zgemm, ssymm, dsymm, csymm, zsymm, ssyrk, dsyrk, csyrk, zsyrk, ssyr2k, dsyr2k, csyr2k, zsyr2k, chemm, zhemm, cherk, zherk, cher2k, zher2k, strmm, dtrmm, ctrmm, ztrmm, strsm, dtrsm, ctrsm, ztrsm) where
 import Prelude hiding (Either(Left, Right))
 import Data.Complex (Complex)
@@ -38,7 +35,7 @@
   let {res' = fromCFloat res} in
   return (res')
 
-{-# LINE 24 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 21 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dsdot :: (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ((Double))
@@ -52,7 +49,7 @@
   let {res' = fromCDouble res} in
   return (res')
 
-{-# LINE 26 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 23 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 sdot :: (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ((Float))
@@ -66,7 +63,7 @@
   let {res' = fromCFloat res} in
   return (res')
 
-{-# LINE 28 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 25 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ddot :: (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ((Double))
@@ -80,7 +77,7 @@
   let {res' = fromCDouble res} in
   return (res')
 
-{-# LINE 30 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 27 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cdotu_sub :: (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> IO ()
@@ -94,7 +91,7 @@
   cdotu_sub'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 32 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 29 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zdotu_sub :: (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> IO ()
@@ -108,7 +105,7 @@
   zdotu_sub'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 34 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 31 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cdotc_sub :: (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> IO ()
@@ -122,7 +119,7 @@
   cdotc_sub'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 36 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 33 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zdotc_sub :: (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> IO ()
@@ -136,7 +133,7 @@
   zdotc_sub'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 38 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 35 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 snrm2 :: (Int) -> (Ptr Float) -> (Int) -> IO ((Float))
@@ -148,7 +145,7 @@
   let {res' = fromCFloat res} in
   return (res')
 
-{-# LINE 40 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 37 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dnrm2 :: (Int) -> (Ptr Double) -> (Int) -> IO ((Double))
@@ -160,7 +157,7 @@
   let {res' = fromCDouble res} in
   return (res')
 
-{-# LINE 42 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 39 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 scnrm2 :: (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ((Float))
@@ -172,7 +169,7 @@
   let {res' = fromCFloat res} in
   return (res')
 
-{-# LINE 44 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 41 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dznrm2 :: (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ((Double))
@@ -184,7 +181,7 @@
   let {res' = fromCDouble res} in
   return (res')
 
-{-# LINE 46 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 43 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 sasum :: (Int) -> (Ptr Float) -> (Int) -> IO ((Float))
@@ -196,7 +193,7 @@
   let {res' = fromCFloat res} in
   return (res')
 
-{-# LINE 48 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 45 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dasum :: (Int) -> (Ptr Double) -> (Int) -> IO ((Double))
@@ -208,7 +205,7 @@
   let {res' = fromCDouble res} in
   return (res')
 
-{-# LINE 50 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 47 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 scasum :: (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ((Float))
@@ -220,7 +217,7 @@
   let {res' = fromCFloat res} in
   return (res')
 
-{-# LINE 52 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 49 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dzasum :: (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ((Double))
@@ -232,7 +229,7 @@
   let {res' = fromCDouble res} in
   return (res')
 
-{-# LINE 54 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 51 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 isamax :: (Int) -> (Ptr Float) -> (Int) -> IO ((Int))
@@ -244,7 +241,7 @@
   let {res' = fromIntegral res} in
   return (res')
 
-{-# LINE 56 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 53 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 idamax :: (Int) -> (Ptr Double) -> (Int) -> IO ((Int))
@@ -256,7 +253,7 @@
   let {res' = fromIntegral res} in
   return (res')
 
-{-# LINE 58 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 55 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 icamax :: (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ((Int))
@@ -268,7 +265,7 @@
   let {res' = fromIntegral res} in
   return (res')
 
-{-# LINE 60 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 57 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 izamax :: (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ((Int))
@@ -280,7 +277,7 @@
   let {res' = fromIntegral res} in
   return (res')
 
-{-# LINE 62 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 59 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 sswap :: (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -293,7 +290,7 @@
   sswap'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 64 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 61 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dswap :: (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -306,7 +303,7 @@
   dswap'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 66 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 63 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cswap :: (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -319,7 +316,7 @@
   cswap'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 68 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 65 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zswap :: (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -332,7 +329,7 @@
   zswap'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 70 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 67 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 scopy :: (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -345,7 +342,7 @@
   scopy'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 72 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 69 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dcopy :: (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -358,7 +355,7 @@
   dcopy'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 74 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 71 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ccopy :: (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -371,7 +368,7 @@
   ccopy'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 76 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 73 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zcopy :: (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -384,7 +381,7 @@
   zcopy'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 78 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 75 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 saxpy :: (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -398,7 +395,7 @@
   saxpy'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 80 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 77 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 daxpy :: (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -412,7 +409,7 @@
   daxpy'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 82 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 79 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 caxpy :: (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -426,7 +423,7 @@
   caxpy'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 84 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 81 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zaxpy :: (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -440,7 +437,7 @@
   zaxpy'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 86 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 83 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 srotg :: (Ptr Float) -> (Ptr Float) -> (Ptr Float) -> (Ptr Float) -> IO ()
@@ -452,7 +449,7 @@
   srotg'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 88 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 85 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 drotg :: (Ptr Double) -> (Ptr Double) -> (Ptr Double) -> (Ptr Double) -> IO ()
@@ -464,7 +461,7 @@
   drotg'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 90 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 87 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 srotmg :: (Ptr Float) -> (Ptr Float) -> (Ptr Float) -> (Float) -> (Ptr Float) -> IO ()
@@ -477,7 +474,7 @@
   srotmg'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 92 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 89 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 drotmg :: (Ptr Double) -> (Ptr Double) -> (Ptr Double) -> (Double) -> (Ptr Double) -> IO ()
@@ -490,7 +487,7 @@
   drotmg'_ a1' a2' a3' a4' a5' >>
   return ()
 
-{-# LINE 94 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 91 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 srot :: (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Float) -> IO ()
@@ -505,7 +502,7 @@
   srot'_ a1' a2' a3' a4' a5' a6' a7' >>
   return ()
 
-{-# LINE 96 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 93 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 drot :: (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Double) -> IO ()
@@ -520,7 +517,7 @@
   drot'_ a1' a2' a3' a4' a5' a6' a7' >>
   return ()
 
-{-# LINE 98 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 95 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 srotm :: (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> IO ()
@@ -534,7 +531,7 @@
   srotm'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 100 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 97 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 drotm :: (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> IO ()
@@ -548,7 +545,7 @@
   drotm'_ a1' a2' a3' a4' a5' a6' >>
   return ()
 
-{-# LINE 102 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 99 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 sscal :: (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -560,7 +557,7 @@
   sscal'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 104 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 101 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dscal :: (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -572,7 +569,7 @@
   dscal'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 106 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 103 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cscal :: (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -584,7 +581,7 @@
   cscal'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 108 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 105 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 csscal :: (Int) -> (Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -596,7 +593,7 @@
   csscal'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 110 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 107 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zscal :: (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -608,7 +605,7 @@
   zscal'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 112 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 109 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zdscal :: (Int) -> (Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -620,7 +617,7 @@
   zdscal'_ a1' a2' a3' a4' >>
   return ()
 
-{-# LINE 114 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 111 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 sgemv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -640,7 +637,7 @@
   sgemv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 116 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 113 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dgemv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -660,7 +657,7 @@
   dgemv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 118 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 115 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cgemv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -680,7 +677,7 @@
   cgemv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 120 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 117 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zgemv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -700,7 +697,7 @@
   zgemv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 122 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 119 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 sgbmv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -722,7 +719,7 @@
   sgbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 124 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 121 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dgbmv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -744,7 +741,7 @@
   dgbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 126 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 123 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cgbmv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -766,7 +763,7 @@
   cgbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 128 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 125 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zgbmv :: (Order) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -788,7 +785,7 @@
   zgbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 130 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 127 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 strmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -805,7 +802,7 @@
   strmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 132 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 129 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dtrmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -822,7 +819,7 @@
   dtrmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 134 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 131 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ctrmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -839,7 +836,7 @@
   ctrmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 136 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 133 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ztrmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -856,7 +853,7 @@
   ztrmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 138 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 135 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 stbmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -874,7 +871,7 @@
   stbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 140 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 137 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dtbmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -892,7 +889,7 @@
   dtbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 142 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 139 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ctbmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -910,7 +907,7 @@
   ctbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 144 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 141 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ztbmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -928,7 +925,7 @@
   ztbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 146 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 143 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 stpmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -944,7 +941,7 @@
   stpmv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 148 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 145 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dtpmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -960,7 +957,7 @@
   dtpmv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 150 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 147 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ctpmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Float)) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -976,7 +973,7 @@
   ctpmv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 152 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 149 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ztpmv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Double)) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -992,7 +989,7 @@
   ztpmv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 154 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 151 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 strsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -1009,7 +1006,7 @@
   strsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 156 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 153 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dtrsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -1026,7 +1023,7 @@
   dtrsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 158 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 155 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ctrsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1043,7 +1040,7 @@
   ctrsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 160 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 157 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ztrsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1060,7 +1057,7 @@
   ztrsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 162 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 159 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 stbsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -1078,7 +1075,7 @@
   stbsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 164 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 161 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dtbsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -1096,7 +1093,7 @@
   dtbsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 166 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 163 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ctbsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1114,7 +1111,7 @@
   ctbsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 168 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 165 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ztbsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1132,7 +1129,7 @@
   ztbsv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 170 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 167 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 stpsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1148,7 +1145,7 @@
   stpsv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 172 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 169 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dtpsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -1164,7 +1161,7 @@
   dtpsv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 174 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 171 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ctpsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Float)) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1180,7 +1177,7 @@
   ctpsv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 176 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 173 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ztpsv :: (Order) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Ptr (Complex Double)) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1196,7 +1193,7 @@
   ztpsv'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 178 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 175 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ssymv :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1215,7 +1212,7 @@
   ssymv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 180 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 177 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dsymv :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -1234,7 +1231,7 @@
   dsymv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 182 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 179 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ssbmv :: (Order) -> (Uplo) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1254,7 +1251,7 @@
   ssbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 184 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 181 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dsbmv :: (Order) -> (Uplo) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -1274,7 +1271,7 @@
   dsbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 186 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 183 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 sspmv :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr Float) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1292,7 +1289,7 @@
   sspmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 188 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 185 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dspmv :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr Double) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -1310,7 +1307,7 @@
   dspmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 190 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 187 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 sger :: (Order) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -1328,7 +1325,7 @@
   sger'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 192 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 189 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dger :: (Order) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -1346,7 +1343,7 @@
   dger'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 194 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 191 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ssyr :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -1362,7 +1359,7 @@
   ssyr'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 196 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 193 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dsyr :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -1378,7 +1375,7 @@
   dsyr'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 198 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 195 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ssyr2 :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -1396,7 +1393,7 @@
   ssyr2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 200 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 197 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dsyr2 :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -1414,7 +1411,7 @@
   dsyr2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 202 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 199 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 sspr :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> IO ()
@@ -1429,7 +1426,7 @@
   sspr'_ a1' a2' a3' a4' a5' a6' a7' >>
   return ()
 
-{-# LINE 204 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 201 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dspr :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> IO ()
@@ -1444,7 +1441,7 @@
   dspr'_ a1' a2' a3' a4' a5' a6' a7' >>
   return ()
 
-{-# LINE 206 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 203 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 sspr2 :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Ptr Float) -> IO ()
@@ -1461,7 +1458,7 @@
   sspr2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 208 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 205 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dspr2 :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Ptr Double) -> IO ()
@@ -1478,7 +1475,7 @@
   dspr2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 210 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 207 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 chemv :: (Order) -> (Uplo) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1497,7 +1494,7 @@
   chemv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 212 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 209 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zhemv :: (Order) -> (Uplo) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1516,7 +1513,7 @@
   zhemv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 214 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 211 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 chbmv :: (Order) -> (Uplo) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1536,7 +1533,7 @@
   chbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 216 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 213 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zhbmv :: (Order) -> (Uplo) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1556,7 +1553,7 @@
   zhbmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 218 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 215 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 chpmv :: (Order) -> (Uplo) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1574,7 +1571,7 @@
   chpmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 220 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 217 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zhpmv :: (Order) -> (Uplo) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1592,7 +1589,7 @@
   zhpmv'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 222 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 219 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cgeru :: (Order) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1610,7 +1607,7 @@
   cgeru'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 224 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 221 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zgeru :: (Order) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1628,7 +1625,7 @@
   zgeru'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 226 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 223 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cgerc :: (Order) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1646,7 +1643,7 @@
   cgerc'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 228 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 225 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zgerc :: (Order) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1664,7 +1661,7 @@
   zgerc'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 230 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 227 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cher :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1680,7 +1677,7 @@
   cher'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 232 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 229 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zher :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1696,7 +1693,7 @@
   zher'_ a1' a2' a3' a4' a5' a6' a7' a8' >>
   return ()
 
-{-# LINE 234 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 231 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 chpr :: (Order) -> (Uplo) -> (Int) -> (Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> IO ()
@@ -1711,7 +1708,7 @@
   chpr'_ a1' a2' a3' a4' a5' a6' a7' >>
   return ()
 
-{-# LINE 236 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 233 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zhpr :: (Order) -> (Uplo) -> (Int) -> (Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> IO ()
@@ -1726,7 +1723,7 @@
   zhpr'_ a1' a2' a3' a4' a5' a6' a7' >>
   return ()
 
-{-# LINE 238 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 235 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cher2 :: (Order) -> (Uplo) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1744,7 +1741,7 @@
   cher2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 240 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 237 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zher2 :: (Order) -> (Uplo) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1762,7 +1759,7 @@
   zher2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' >>
   return ()
 
-{-# LINE 242 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 239 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 chpr2 :: (Order) -> (Uplo) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> IO ()
@@ -1779,7 +1776,7 @@
   chpr2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 244 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 241 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zhpr2 :: (Order) -> (Uplo) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> IO ()
@@ -1796,7 +1793,7 @@
   zhpr2'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' >>
   return ()
 
-{-# LINE 246 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 243 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 sgemm :: (Order) -> (Transpose) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1818,7 +1815,7 @@
   sgemm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 248 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 245 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dgemm :: (Order) -> (Transpose) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -1840,7 +1837,7 @@
   dgemm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 250 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 247 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cgemm :: (Order) -> (Transpose) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1862,7 +1859,7 @@
   cgemm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 252 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 249 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zgemm :: (Order) -> (Transpose) -> (Transpose) -> (Int) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1884,7 +1881,7 @@
   zgemm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' a14' >>
   return ()
 
-{-# LINE 254 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 251 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ssymm :: (Order) -> (Side) -> (Uplo) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1905,7 +1902,7 @@
   ssymm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 256 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 253 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dsymm :: (Order) -> (Side) -> (Uplo) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -1926,7 +1923,7 @@
   dsymm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 258 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 255 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 csymm :: (Order) -> (Side) -> (Uplo) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -1947,7 +1944,7 @@
   csymm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 260 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 257 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zsymm :: (Order) -> (Side) -> (Uplo) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -1968,7 +1965,7 @@
   zsymm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 262 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 259 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ssyrk :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -1987,7 +1984,7 @@
   ssyrk'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 264 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 261 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dsyrk :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -2006,7 +2003,7 @@
   dsyrk'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 266 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 263 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 csyrk :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2025,7 +2022,7 @@
   csyrk'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 268 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 265 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zsyrk :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2044,7 +2041,7 @@
   zsyrk'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 270 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 267 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ssyr2k :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> IO ()
@@ -2065,7 +2062,7 @@
   ssyr2k'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 272 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 269 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dsyr2k :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> IO ()
@@ -2086,7 +2083,7 @@
   dsyr2k'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 274 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 271 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 csyr2k :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2107,7 +2104,7 @@
   csyr2k'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 276 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 273 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zsyr2k :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2128,7 +2125,7 @@
   zsyr2k'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 278 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 275 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 chemm :: (Order) -> (Side) -> (Uplo) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2149,7 +2146,7 @@
   chemm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 280 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 277 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zhemm :: (Order) -> (Side) -> (Uplo) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2170,7 +2167,7 @@
   zhemm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 282 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 279 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cherk :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Float) -> (Ptr (Complex Float)) -> (Int) -> (Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2189,7 +2186,7 @@
   cherk'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 284 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 281 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zherk :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Double) -> (Ptr (Complex Double)) -> (Int) -> (Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2208,7 +2205,7 @@
   zherk'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' >>
   return ()
 
-{-# LINE 286 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 283 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 cher2k :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> (Float) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2229,7 +2226,7 @@
   cher2k'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 288 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 285 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 zher2k :: (Order) -> (Uplo) -> (Transpose) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> (Double) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2250,7 +2247,7 @@
   zher2k'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' a13' >>
   return ()
 
-{-# LINE 290 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 287 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 strmm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -2270,7 +2267,7 @@
   strmm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 292 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 289 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dtrmm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -2290,7 +2287,7 @@
   dtrmm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 294 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 291 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ctrmm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2310,7 +2307,7 @@
   ctrmm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 296 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 293 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ztrmm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2330,7 +2327,7 @@
   ztrmm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 298 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 295 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 strsm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Float) -> (Ptr Float) -> (Int) -> (Ptr Float) -> (Int) -> IO ()
@@ -2350,7 +2347,7 @@
   strsm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 300 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 297 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 dtrsm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Double) -> (Ptr Double) -> (Int) -> (Ptr Double) -> (Int) -> IO ()
@@ -2370,7 +2367,7 @@
   dtrsm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 302 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 299 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ctrsm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Complex Float) -> (Ptr (Complex Float)) -> (Int) -> (Ptr (Complex Float)) -> (Int) -> IO ()
@@ -2390,7 +2387,7 @@
   ctrsm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 304 "src/Blas/Primitive/Unsafe_.chs" #-}
+{-# LINE 301 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 
 ztrsm :: (Order) -> (Side) -> (Uplo) -> (Transpose) -> (Diag) -> (Int) -> (Int) -> (Complex Double) -> (Ptr (Complex Double)) -> (Int) -> (Ptr (Complex Double)) -> (Int) -> IO ()
@@ -2410,8 +2407,7 @@
   ztrsm'_ a1' a2' a3' a4' a5' a6' a7' a8' a9' a10' a11' a12' >>
   return ()
 
-{-# LINE 306 "src/Blas/Primitive/Unsafe_.chs" #-}
-
+{-# LINE 21 "src/Blas/Primitive/Unsafe_.chs" #-}
 
 foreign import ccall unsafe "src/Blas/Primitive/Unsafe_.chs.h cblas_sdsdot"
   sdsdot'_ :: (BlasInt -> (CFloat -> ((Ptr CFloat) -> (BlasInt -> ((Ptr CFloat) -> (BlasInt -> (IO CFloat)))))))
diff --git a/src/Blas/Specialized/ComplexDouble/Safe.hs b/src/Blas/Specialized/ComplexDouble/Safe.hs
new file mode 100644
--- /dev/null
+++ b/src/Blas/Specialized/ComplexDouble/Safe.hs
@@ -0,0 +1,660 @@
+-- This file is auto-generated.  Do not edit directly.
+-- |
+--   Stability: Experimental
+--
+--   Generic interface to Blas using safe foreign calls.  Refer to the GHC documentation
+--   for more information regarding appropriate use of safe and unsafe foreign calls.
+--
+--   The functions here are named in a similar fashion to the original Blas interface, with
+--   the type-dependent letter(s) removed.  Some functions have been merged with
+--   others to allow the interface to work on both real and complex numbers.  If you can't a
+--   particular function, try looking for its corresponding complex equivalent (e.g.
+--   @symv@ is a special case of 'hemv' applied to real numbers).
+--
+--   Note: although complex versions of 'rot' and 'rotg' exist in many implementations,
+--   they are not part of the official Blas standard and therefore not included here.  If
+--   you /really/ need them, submit a ticket so we can try to come up with a solution.
+--
+--   The documentation here is still incomplete.  Consult the
+--   <http://netlib.org/blas/#_blas_routines official documentation> for more
+--   information.
+--
+--   Notation:
+--
+--     * @⋅@ denotes dot product (without any conjugation).
+--     * @*@ denotes complex conjugation.
+--     * @⊤@ denotes transpose.
+--     * @†@ denotes conjugate transpose (Hermitian conjugate).
+--
+--   Conventions:
+--
+--     * All scalars are denoted with lowercase Greek letters
+--     * All vectors are denoted with lowercase Latin letters and are
+--       assumed to be column vectors (unless transposed).
+--     * All matrices are denoted with uppercase Latin letters.
+--
+--   /Since: 0.1.1/
+module Blas.Specialized.ComplexDouble.Safe (
+  -- * Level 1: vector-vector operations
+  -- ** Basic operations
+    swap
+  , scal
+  , copy
+  , axpy
+  , dotu
+  , dotc
+  -- ** Norm operations
+  , nrm2
+  , asum
+  , iamax
+  -- * Level 2: matrix-vector operations
+  -- ** Multiplication
+  , gemv
+  , gbmv
+  , hemv
+  , hbmv
+  , hpmv
+  -- ** Triangular operations
+  , trmv
+  , tbmv
+  , tpmv
+  , trsv
+  , tbsv
+  , tpsv
+  -- ** Rank updates
+  , geru
+  , gerc
+  , her
+  , hpr
+  , her2
+  , hpr2
+  -- * Level 3: matrix-matrix operations
+  -- ** Multiplication
+  , gemm
+  , symm
+  , hemm
+  -- ** Rank updates
+  , syrk
+  , herk
+  , syr2k
+  , her2k
+  -- ** Triangular operations
+  , trmm
+  , trsm
+  ) where
+import Foreign (Ptr)
+import Data.Complex (Complex((:+)))
+import FFI (getReturnValue)
+import Blas.Primitive.Types (Order, Transpose, Uplo, Diag, Side)
+import qualified Blas.Primitive.Safe as C
+
+-- | Swap two vectors:
+--
+--   > (x, y) ← (y, x)
+swap :: Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+swap = C.zswap
+
+
+-- | Multiply a vector by a scalar.
+--
+--   > x ← α x
+scal :: Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+scal n (alpha :+ 0) = C.zdscal n alpha
+scal n alpha = C.zscal n alpha
+
+
+-- | Copy a vector into another vector:
+--
+--   > y ← x
+copy :: Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+copy = C.zcopy
+
+
+-- | Add a scalar-vector product to a vector.
+--
+--   > y ← α x + y
+axpy :: Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+axpy = C.zaxpy
+
+
+-- | Calculate the bilinear dot product of two vectors:
+--
+--   > x ⋅ y ≡ ∑[i] x[i] y[i]
+dotu :: Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO (Complex Double)
+dotu a b c d e = getReturnValue (C.zdotu_sub a b c d e)
+
+
+-- | Calculate the sesquilinear dot product of two vectors.
+--
+--   > x* ⋅ y ≡ ∑[i] x[i]* y[i]
+dotc :: Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO (Complex Double)
+dotc a b c d e = getReturnValue (C.zdotc_sub a b c d e)
+
+
+-- | Calculate the Euclidean (L²) norm of a vector:
+--
+--   > ‖x‖₂ ≡ √(∑[i] x[i]²)
+nrm2 :: Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO Double
+nrm2 = C.dznrm2
+
+
+-- | Calculate the Manhattan (L¹) norm, equal to the sum of the magnitudes of the elements:
+--
+--   > ‖x‖₁ = ∑[i] |x[i]|
+asum :: Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO Double
+asum = C.dzasum
+
+
+-- | Calculate the index of the element with the maximum magnitude (absolute value).
+iamax :: Int
+      -> Ptr (Complex Double)
+      -> Int
+      -> IO Int
+iamax = C.izamax
+
+
+-- | Perform a general matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gemv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+gemv = C.zgemv
+
+
+-- | Perform a general banded matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gbmv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+gbmv = C.zgbmv
+
+
+-- | Perform a hermitian matrix-vector update.
+--
+--   > y ← α A x + β y
+hemv :: Order
+     -> Uplo
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+hemv = C.zhemv
+
+
+-- | Perform a hermitian banded matrix-vector update.
+--
+--   > y ← α A x + β y
+hbmv :: Order
+     -> Uplo
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+hbmv = C.zhbmv
+
+
+-- | Perform a hermitian packed matrix-vector update.
+--
+--   > y ← α A x + β y
+hpmv :: Order
+     -> Uplo
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Ptr (Complex Double)
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+hpmv = C.zhpmv
+
+
+-- | Multiply a triangular matrix by a vector.
+--
+--   > x ← T(A) x
+trmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+trmv = C.ztrmv
+
+
+-- | Multiply a triangular banded matrix by a vector.
+--
+--   > x ← T(A) x
+tbmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+tbmv = C.ztbmv
+
+
+-- | Multiply a triangular packed matrix by a vector.
+--
+--   > x ← T(A) x
+tpmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Double)
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+tpmv = C.ztpmv
+
+
+-- | Multiply an inverse triangular matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+trsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+trsv = C.ztrsv
+
+
+-- | Multiply an inverse triangular banded matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tbsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+tbsv = C.ztbsv
+
+
+-- | Multiply an inverse triangular packed matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tpsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Double)
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+tpsv = C.ztpsv
+
+
+-- | Perform an unconjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y⊤ + A
+geru :: Order
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+geru = C.zgeru
+
+
+-- | Perform a conjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y† + A
+gerc :: Order
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+gerc = C.zgerc
+
+
+-- | Perform a rank-1 update of a Hermitian matrix.
+--
+--   > A ← α x y† + A
+her :: Order
+    -> Uplo
+    -> Int
+    -> Double
+    -> Ptr (Complex Double)
+    -> Int
+    -> Ptr (Complex Double)
+    -> Int
+    -> IO ()
+her = C.zher
+
+
+-- | Perform a rank-1 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + A
+hpr :: Order
+    -> Uplo
+    -> Int
+    -> Double
+    -> Ptr (Complex Double)
+    -> Int
+    -> Ptr (Complex Double)
+    -> IO ()
+hpr = C.zhpr
+
+
+-- | Perform a rank-2 update of a Hermitian matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+her2 :: Order
+     -> Uplo
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+her2 = C.zher2
+
+
+-- | Perform a rank-2 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+hpr2 :: Order
+     -> Uplo
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> IO ()
+hpr2 = C.zhpr2
+
+
+-- | Perform a general matrix-matrix update.
+--
+--   > C ← α T(A) U(B) + β C
+gemm :: Order -- ^ Layout of all the matrices.
+     -> Transpose -- ^ The operation @T@ to be applied to @A@.
+     -> Transpose -- ^ The operation @U@ to be applied to @B@.
+     -> Int -- ^ Number of rows of @T(A)@ and @C@.
+     -> Int -- ^ Number of columns of @U(B)@ and @C@.
+     -> Int -- ^ Number of columns of @T(A)@ and number of rows of @U(B)@.
+     -> Complex Double -- ^ Scaling factor @α@ of the product.
+     -> Ptr (Complex Double) -- ^ Pointer to a matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr (Complex Double) -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Complex Double -- ^ Scaling factor @β@ of the original @C@.
+     -> Ptr (Complex Double) -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+gemm = C.zgemm
+
+
+-- | Perform a symmetric matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is symmetric.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+symm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Complex Double -- ^ Scaling factor @α@ of the product.
+     -> Ptr (Complex Double) -- ^ Pointer to a symmetric matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr (Complex Double) -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Complex Double -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr (Complex Double) -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+symm = C.zsymm
+
+
+-- | Perform a Hermitian matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is Hermitian.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+hemm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Complex Double -- ^ Scaling factor @α@ of the product.
+     -> Ptr (Complex Double) -- ^ Pointer to a Hermitian matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr (Complex Double) -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Complex Double -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr (Complex Double) -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+hemm = C.zhemm
+
+
+-- | Perform a symmetric rank-k update.
+--
+--   > C ← α A A⊤ + β C    or    C ← α A⊤ A + β C
+syrk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+syrk = C.zsyrk
+
+
+-- | Perform a Hermitian rank-k update.
+--
+--   > C ← α A A† + β C    or    C ← α A† A + β C
+herk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+herk = C.zherk
+
+
+-- | Perform a symmetric rank-2k update.
+--
+--   > C ← α A B⊤ + α* B A⊤ + β C    or    C ← α A⊤ B + α* B⊤ A + β C
+syr2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Complex Double
+      -> Ptr (Complex Double)
+      -> Int
+      -> Ptr (Complex Double)
+      -> Int
+      -> Complex Double
+      -> Ptr (Complex Double)
+      -> Int
+      -> IO ()
+syr2k = C.zsyr2k
+
+
+-- | Perform a Hermitian rank-2k update.
+--
+--   > C ← α A B† + α* B A† + β C    or    C ← α A† B + α* B† A + β C
+her2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Complex Double
+      -> Ptr (Complex Double)
+      -> Int
+      -> Ptr (Complex Double)
+      -> Int
+      -> Double
+      -> Ptr (Complex Double)
+      -> Int
+      -> IO ()
+her2k = C.zher2k
+
+
+-- | Perform a triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A) B    or    B ← α B T(A)
+--
+--   where @A@ is triangular.
+trmm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+trmm = C.ztrmm
+
+
+-- | Perform an inverse triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A⁻¹) B    or    B ← α B T(A⁻¹)
+--
+--   where @A@ is triangular.
+trsm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+trsm = C.ztrsm
diff --git a/src/Blas/Specialized/ComplexDouble/Unsafe.hs b/src/Blas/Specialized/ComplexDouble/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/src/Blas/Specialized/ComplexDouble/Unsafe.hs
@@ -0,0 +1,661 @@
+-- This file is auto-generated.  Do not edit directly.
+-- |
+--   Stability: Experimental
+--
+--   Generic interface to Blas using unsafe foreign calls.  Refer to the GHC
+--   documentation for more information regarding appropriate use of safe and unsafe
+--   foreign calls.
+--
+--   The functions here are named in a similar fashion to the original Blas interface, with
+--   the type-dependent letter(s) removed.  Some functions have been merged with
+--   others to allow the interface to work on both real and complex numbers.  If you can't a
+--   particular function, try looking for its corresponding complex equivalent (e.g.
+--   @symv@ is a special case of 'hemv' applied to real numbers).
+--
+--   Note: although complex versions of 'rot' and 'rotg' exist in many implementations,
+--   they are not part of the official Blas standard and therefore not included here.  If
+--   you /really/ need them, submit a ticket so we can try to come up with a solution.
+--
+--   The documentation here is still incomplete.  Consult the
+--   <http://netlib.org/blas/#_blas_routines official documentation> for more
+--   information.
+--
+--   Notation:
+--
+--     * @⋅@ denotes dot product (without any conjugation).
+--     * @*@ denotes complex conjugation.
+--     * @⊤@ denotes transpose.
+--     * @†@ denotes conjugate transpose (Hermitian conjugate).
+--
+--   Conventions:
+--
+--     * All scalars are denoted with lowercase Greek letters
+--     * All vectors are denoted with lowercase Latin letters and are
+--       assumed to be column vectors (unless transposed).
+--     * All matrices are denoted with uppercase Latin letters.
+--
+--   /Since: 0.1.1/
+module Blas.Specialized.ComplexDouble.Unsafe (
+  -- * Level 1: vector-vector operations
+  -- ** Basic operations
+    swap
+  , scal
+  , copy
+  , axpy
+  , dotu
+  , dotc
+  -- ** Norm operations
+  , nrm2
+  , asum
+  , iamax
+  -- * Level 2: matrix-vector operations
+  -- ** Multiplication
+  , gemv
+  , gbmv
+  , hemv
+  , hbmv
+  , hpmv
+  -- ** Triangular operations
+  , trmv
+  , tbmv
+  , tpmv
+  , trsv
+  , tbsv
+  , tpsv
+  -- ** Rank updates
+  , geru
+  , gerc
+  , her
+  , hpr
+  , her2
+  , hpr2
+  -- * Level 3: matrix-matrix operations
+  -- ** Multiplication
+  , gemm
+  , symm
+  , hemm
+  -- ** Rank updates
+  , syrk
+  , herk
+  , syr2k
+  , her2k
+  -- ** Triangular operations
+  , trmm
+  , trsm
+  ) where
+import Foreign (Ptr)
+import Data.Complex (Complex((:+)))
+import FFI (getReturnValue)
+import Blas.Primitive.Types (Order, Transpose, Uplo, Diag, Side)
+import qualified Blas.Primitive.Unsafe as C
+
+-- | Swap two vectors:
+--
+--   > (x, y) ← (y, x)
+swap :: Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+swap = C.zswap
+
+
+-- | Multiply a vector by a scalar.
+--
+--   > x ← α x
+scal :: Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+scal n (alpha :+ 0) = C.zdscal n alpha
+scal n alpha = C.zscal n alpha
+
+
+-- | Copy a vector into another vector:
+--
+--   > y ← x
+copy :: Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+copy = C.zcopy
+
+
+-- | Add a scalar-vector product to a vector.
+--
+--   > y ← α x + y
+axpy :: Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+axpy = C.zaxpy
+
+
+-- | Calculate the bilinear dot product of two vectors:
+--
+--   > x ⋅ y ≡ ∑[i] x[i] y[i]
+dotu :: Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO (Complex Double)
+dotu a b c d e = getReturnValue (C.zdotu_sub a b c d e)
+
+
+-- | Calculate the sesquilinear dot product of two vectors.
+--
+--   > x* ⋅ y ≡ ∑[i] x[i]* y[i]
+dotc :: Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO (Complex Double)
+dotc a b c d e = getReturnValue (C.zdotc_sub a b c d e)
+
+
+-- | Calculate the Euclidean (L²) norm of a vector:
+--
+--   > ‖x‖₂ ≡ √(∑[i] x[i]²)
+nrm2 :: Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO Double
+nrm2 = C.dznrm2
+
+
+-- | Calculate the Manhattan (L¹) norm, equal to the sum of the magnitudes of the elements:
+--
+--   > ‖x‖₁ = ∑[i] |x[i]|
+asum :: Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO Double
+asum = C.dzasum
+
+
+-- | Calculate the index of the element with the maximum magnitude (absolute value).
+iamax :: Int
+      -> Ptr (Complex Double)
+      -> Int
+      -> IO Int
+iamax = C.izamax
+
+
+-- | Perform a general matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gemv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+gemv = C.zgemv
+
+
+-- | Perform a general banded matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gbmv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+gbmv = C.zgbmv
+
+
+-- | Perform a hermitian matrix-vector update.
+--
+--   > y ← α A x + β y
+hemv :: Order
+     -> Uplo
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+hemv = C.zhemv
+
+
+-- | Perform a hermitian banded matrix-vector update.
+--
+--   > y ← α A x + β y
+hbmv :: Order
+     -> Uplo
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+hbmv = C.zhbmv
+
+
+-- | Perform a hermitian packed matrix-vector update.
+--
+--   > y ← α A x + β y
+hpmv :: Order
+     -> Uplo
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Ptr (Complex Double)
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+hpmv = C.zhpmv
+
+
+-- | Multiply a triangular matrix by a vector.
+--
+--   > x ← T(A) x
+trmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+trmv = C.ztrmv
+
+
+-- | Multiply a triangular banded matrix by a vector.
+--
+--   > x ← T(A) x
+tbmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+tbmv = C.ztbmv
+
+
+-- | Multiply a triangular packed matrix by a vector.
+--
+--   > x ← T(A) x
+tpmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Double)
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+tpmv = C.ztpmv
+
+
+-- | Multiply an inverse triangular matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+trsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+trsv = C.ztrsv
+
+
+-- | Multiply an inverse triangular banded matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tbsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+tbsv = C.ztbsv
+
+
+-- | Multiply an inverse triangular packed matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tpsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Double)
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+tpsv = C.ztpsv
+
+
+-- | Perform an unconjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y⊤ + A
+geru :: Order
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+geru = C.zgeru
+
+
+-- | Perform a conjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y† + A
+gerc :: Order
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+gerc = C.zgerc
+
+
+-- | Perform a rank-1 update of a Hermitian matrix.
+--
+--   > A ← α x y† + A
+her :: Order
+    -> Uplo
+    -> Int
+    -> Double
+    -> Ptr (Complex Double)
+    -> Int
+    -> Ptr (Complex Double)
+    -> Int
+    -> IO ()
+her = C.zher
+
+
+-- | Perform a rank-1 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + A
+hpr :: Order
+    -> Uplo
+    -> Int
+    -> Double
+    -> Ptr (Complex Double)
+    -> Int
+    -> Ptr (Complex Double)
+    -> IO ()
+hpr = C.zhpr
+
+
+-- | Perform a rank-2 update of a Hermitian matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+her2 :: Order
+     -> Uplo
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+her2 = C.zher2
+
+
+-- | Perform a rank-2 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+hpr2 :: Order
+     -> Uplo
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> IO ()
+hpr2 = C.zhpr2
+
+
+-- | Perform a general matrix-matrix update.
+--
+--   > C ← α T(A) U(B) + β C
+gemm :: Order -- ^ Layout of all the matrices.
+     -> Transpose -- ^ The operation @T@ to be applied to @A@.
+     -> Transpose -- ^ The operation @U@ to be applied to @B@.
+     -> Int -- ^ Number of rows of @T(A)@ and @C@.
+     -> Int -- ^ Number of columns of @U(B)@ and @C@.
+     -> Int -- ^ Number of columns of @T(A)@ and number of rows of @U(B)@.
+     -> Complex Double -- ^ Scaling factor @α@ of the product.
+     -> Ptr (Complex Double) -- ^ Pointer to a matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr (Complex Double) -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Complex Double -- ^ Scaling factor @β@ of the original @C@.
+     -> Ptr (Complex Double) -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+gemm = C.zgemm
+
+
+-- | Perform a symmetric matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is symmetric.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+symm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Complex Double -- ^ Scaling factor @α@ of the product.
+     -> Ptr (Complex Double) -- ^ Pointer to a symmetric matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr (Complex Double) -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Complex Double -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr (Complex Double) -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+symm = C.zsymm
+
+
+-- | Perform a Hermitian matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is Hermitian.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+hemm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Complex Double -- ^ Scaling factor @α@ of the product.
+     -> Ptr (Complex Double) -- ^ Pointer to a Hermitian matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr (Complex Double) -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Complex Double -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr (Complex Double) -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+hemm = C.zhemm
+
+
+-- | Perform a symmetric rank-k update.
+--
+--   > C ← α A A⊤ + β C    or    C ← α A⊤ A + β C
+syrk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+syrk = C.zsyrk
+
+
+-- | Perform a Hermitian rank-k update.
+--
+--   > C ← α A A† + β C    or    C ← α A† A + β C
+herk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+herk = C.zherk
+
+
+-- | Perform a symmetric rank-2k update.
+--
+--   > C ← α A B⊤ + α* B A⊤ + β C    or    C ← α A⊤ B + α* B⊤ A + β C
+syr2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Complex Double
+      -> Ptr (Complex Double)
+      -> Int
+      -> Ptr (Complex Double)
+      -> Int
+      -> Complex Double
+      -> Ptr (Complex Double)
+      -> Int
+      -> IO ()
+syr2k = C.zsyr2k
+
+
+-- | Perform a Hermitian rank-2k update.
+--
+--   > C ← α A B† + α* B A† + β C    or    C ← α A† B + α* B† A + β C
+her2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Complex Double
+      -> Ptr (Complex Double)
+      -> Int
+      -> Ptr (Complex Double)
+      -> Int
+      -> Double
+      -> Ptr (Complex Double)
+      -> Int
+      -> IO ()
+her2k = C.zher2k
+
+
+-- | Perform a triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A) B    or    B ← α B T(A)
+--
+--   where @A@ is triangular.
+trmm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+trmm = C.ztrmm
+
+
+-- | Perform an inverse triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A⁻¹) B    or    B ← α B T(A⁻¹)
+--
+--   where @A@ is triangular.
+trsm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Complex Double
+     -> Ptr (Complex Double)
+     -> Int
+     -> Ptr (Complex Double)
+     -> Int
+     -> IO ()
+trsm = C.ztrsm
diff --git a/src/Blas/Specialized/ComplexFloat/Safe.hs b/src/Blas/Specialized/ComplexFloat/Safe.hs
new file mode 100644
--- /dev/null
+++ b/src/Blas/Specialized/ComplexFloat/Safe.hs
@@ -0,0 +1,660 @@
+-- This file is auto-generated.  Do not edit directly.
+-- |
+--   Stability: Experimental
+--
+--   Generic interface to Blas using safe foreign calls.  Refer to the GHC documentation
+--   for more information regarding appropriate use of safe and unsafe foreign calls.
+--
+--   The functions here are named in a similar fashion to the original Blas interface, with
+--   the type-dependent letter(s) removed.  Some functions have been merged with
+--   others to allow the interface to work on both real and complex numbers.  If you can't a
+--   particular function, try looking for its corresponding complex equivalent (e.g.
+--   @symv@ is a special case of 'hemv' applied to real numbers).
+--
+--   Note: although complex versions of 'rot' and 'rotg' exist in many implementations,
+--   they are not part of the official Blas standard and therefore not included here.  If
+--   you /really/ need them, submit a ticket so we can try to come up with a solution.
+--
+--   The documentation here is still incomplete.  Consult the
+--   <http://netlib.org/blas/#_blas_routines official documentation> for more
+--   information.
+--
+--   Notation:
+--
+--     * @⋅@ denotes dot product (without any conjugation).
+--     * @*@ denotes complex conjugation.
+--     * @⊤@ denotes transpose.
+--     * @†@ denotes conjugate transpose (Hermitian conjugate).
+--
+--   Conventions:
+--
+--     * All scalars are denoted with lowercase Greek letters
+--     * All vectors are denoted with lowercase Latin letters and are
+--       assumed to be column vectors (unless transposed).
+--     * All matrices are denoted with uppercase Latin letters.
+--
+--   /Since: 0.1.1/
+module Blas.Specialized.ComplexFloat.Safe (
+  -- * Level 1: vector-vector operations
+  -- ** Basic operations
+    swap
+  , scal
+  , copy
+  , axpy
+  , dotu
+  , dotc
+  -- ** Norm operations
+  , nrm2
+  , asum
+  , iamax
+  -- * Level 2: matrix-vector operations
+  -- ** Multiplication
+  , gemv
+  , gbmv
+  , hemv
+  , hbmv
+  , hpmv
+  -- ** Triangular operations
+  , trmv
+  , tbmv
+  , tpmv
+  , trsv
+  , tbsv
+  , tpsv
+  -- ** Rank updates
+  , geru
+  , gerc
+  , her
+  , hpr
+  , her2
+  , hpr2
+  -- * Level 3: matrix-matrix operations
+  -- ** Multiplication
+  , gemm
+  , symm
+  , hemm
+  -- ** Rank updates
+  , syrk
+  , herk
+  , syr2k
+  , her2k
+  -- ** Triangular operations
+  , trmm
+  , trsm
+  ) where
+import Foreign (Ptr)
+import Data.Complex (Complex((:+)))
+import FFI (getReturnValue)
+import Blas.Primitive.Types (Order, Transpose, Uplo, Diag, Side)
+import qualified Blas.Primitive.Safe as C
+
+-- | Swap two vectors:
+--
+--   > (x, y) ← (y, x)
+swap :: Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+swap = C.cswap
+
+
+-- | Multiply a vector by a scalar.
+--
+--   > x ← α x
+scal :: Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+scal n (alpha :+ 0) = C.csscal n alpha
+scal n alpha = C.cscal n alpha
+
+
+-- | Copy a vector into another vector:
+--
+--   > y ← x
+copy :: Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+copy = C.ccopy
+
+
+-- | Add a scalar-vector product to a vector.
+--
+--   > y ← α x + y
+axpy :: Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+axpy = C.caxpy
+
+
+-- | Calculate the bilinear dot product of two vectors:
+--
+--   > x ⋅ y ≡ ∑[i] x[i] y[i]
+dotu :: Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO (Complex Float)
+dotu a b c d e = getReturnValue (C.cdotu_sub a b c d e)
+
+
+-- | Calculate the sesquilinear dot product of two vectors.
+--
+--   > x* ⋅ y ≡ ∑[i] x[i]* y[i]
+dotc :: Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO (Complex Float)
+dotc a b c d e = getReturnValue (C.cdotc_sub a b c d e)
+
+
+-- | Calculate the Euclidean (L²) norm of a vector:
+--
+--   > ‖x‖₂ ≡ √(∑[i] x[i]²)
+nrm2 :: Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO Float
+nrm2 = C.scnrm2
+
+
+-- | Calculate the Manhattan (L¹) norm, equal to the sum of the magnitudes of the elements:
+--
+--   > ‖x‖₁ = ∑[i] |x[i]|
+asum :: Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO Float
+asum = C.scasum
+
+
+-- | Calculate the index of the element with the maximum magnitude (absolute value).
+iamax :: Int
+      -> Ptr (Complex Float)
+      -> Int
+      -> IO Int
+iamax = C.icamax
+
+
+-- | Perform a general matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gemv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+gemv = C.cgemv
+
+
+-- | Perform a general banded matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gbmv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+gbmv = C.cgbmv
+
+
+-- | Perform a hermitian matrix-vector update.
+--
+--   > y ← α A x + β y
+hemv :: Order
+     -> Uplo
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+hemv = C.chemv
+
+
+-- | Perform a hermitian banded matrix-vector update.
+--
+--   > y ← α A x + β y
+hbmv :: Order
+     -> Uplo
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+hbmv = C.chbmv
+
+
+-- | Perform a hermitian packed matrix-vector update.
+--
+--   > y ← α A x + β y
+hpmv :: Order
+     -> Uplo
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Ptr (Complex Float)
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+hpmv = C.chpmv
+
+
+-- | Multiply a triangular matrix by a vector.
+--
+--   > x ← T(A) x
+trmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+trmv = C.ctrmv
+
+
+-- | Multiply a triangular banded matrix by a vector.
+--
+--   > x ← T(A) x
+tbmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+tbmv = C.ctbmv
+
+
+-- | Multiply a triangular packed matrix by a vector.
+--
+--   > x ← T(A) x
+tpmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Float)
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+tpmv = C.ctpmv
+
+
+-- | Multiply an inverse triangular matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+trsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+trsv = C.ctrsv
+
+
+-- | Multiply an inverse triangular banded matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tbsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+tbsv = C.ctbsv
+
+
+-- | Multiply an inverse triangular packed matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tpsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Float)
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+tpsv = C.ctpsv
+
+
+-- | Perform an unconjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y⊤ + A
+geru :: Order
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+geru = C.cgeru
+
+
+-- | Perform a conjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y† + A
+gerc :: Order
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+gerc = C.cgerc
+
+
+-- | Perform a rank-1 update of a Hermitian matrix.
+--
+--   > A ← α x y† + A
+her :: Order
+    -> Uplo
+    -> Int
+    -> Float
+    -> Ptr (Complex Float)
+    -> Int
+    -> Ptr (Complex Float)
+    -> Int
+    -> IO ()
+her = C.cher
+
+
+-- | Perform a rank-1 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + A
+hpr :: Order
+    -> Uplo
+    -> Int
+    -> Float
+    -> Ptr (Complex Float)
+    -> Int
+    -> Ptr (Complex Float)
+    -> IO ()
+hpr = C.chpr
+
+
+-- | Perform a rank-2 update of a Hermitian matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+her2 :: Order
+     -> Uplo
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+her2 = C.cher2
+
+
+-- | Perform a rank-2 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+hpr2 :: Order
+     -> Uplo
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> IO ()
+hpr2 = C.chpr2
+
+
+-- | Perform a general matrix-matrix update.
+--
+--   > C ← α T(A) U(B) + β C
+gemm :: Order -- ^ Layout of all the matrices.
+     -> Transpose -- ^ The operation @T@ to be applied to @A@.
+     -> Transpose -- ^ The operation @U@ to be applied to @B@.
+     -> Int -- ^ Number of rows of @T(A)@ and @C@.
+     -> Int -- ^ Number of columns of @U(B)@ and @C@.
+     -> Int -- ^ Number of columns of @T(A)@ and number of rows of @U(B)@.
+     -> Complex Float -- ^ Scaling factor @α@ of the product.
+     -> Ptr (Complex Float) -- ^ Pointer to a matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr (Complex Float) -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Complex Float -- ^ Scaling factor @β@ of the original @C@.
+     -> Ptr (Complex Float) -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+gemm = C.cgemm
+
+
+-- | Perform a symmetric matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is symmetric.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+symm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Complex Float -- ^ Scaling factor @α@ of the product.
+     -> Ptr (Complex Float) -- ^ Pointer to a symmetric matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr (Complex Float) -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Complex Float -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr (Complex Float) -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+symm = C.csymm
+
+
+-- | Perform a Hermitian matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is Hermitian.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+hemm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Complex Float -- ^ Scaling factor @α@ of the product.
+     -> Ptr (Complex Float) -- ^ Pointer to a Hermitian matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr (Complex Float) -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Complex Float -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr (Complex Float) -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+hemm = C.chemm
+
+
+-- | Perform a symmetric rank-k update.
+--
+--   > C ← α A A⊤ + β C    or    C ← α A⊤ A + β C
+syrk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+syrk = C.csyrk
+
+
+-- | Perform a Hermitian rank-k update.
+--
+--   > C ← α A A† + β C    or    C ← α A† A + β C
+herk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+herk = C.cherk
+
+
+-- | Perform a symmetric rank-2k update.
+--
+--   > C ← α A B⊤ + α* B A⊤ + β C    or    C ← α A⊤ B + α* B⊤ A + β C
+syr2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Complex Float
+      -> Ptr (Complex Float)
+      -> Int
+      -> Ptr (Complex Float)
+      -> Int
+      -> Complex Float
+      -> Ptr (Complex Float)
+      -> Int
+      -> IO ()
+syr2k = C.csyr2k
+
+
+-- | Perform a Hermitian rank-2k update.
+--
+--   > C ← α A B† + α* B A† + β C    or    C ← α A† B + α* B† A + β C
+her2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Complex Float
+      -> Ptr (Complex Float)
+      -> Int
+      -> Ptr (Complex Float)
+      -> Int
+      -> Float
+      -> Ptr (Complex Float)
+      -> Int
+      -> IO ()
+her2k = C.cher2k
+
+
+-- | Perform a triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A) B    or    B ← α B T(A)
+--
+--   where @A@ is triangular.
+trmm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+trmm = C.ctrmm
+
+
+-- | Perform an inverse triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A⁻¹) B    or    B ← α B T(A⁻¹)
+--
+--   where @A@ is triangular.
+trsm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+trsm = C.ctrsm
diff --git a/src/Blas/Specialized/ComplexFloat/Unsafe.hs b/src/Blas/Specialized/ComplexFloat/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/src/Blas/Specialized/ComplexFloat/Unsafe.hs
@@ -0,0 +1,661 @@
+-- This file is auto-generated.  Do not edit directly.
+-- |
+--   Stability: Experimental
+--
+--   Generic interface to Blas using unsafe foreign calls.  Refer to the GHC
+--   documentation for more information regarding appropriate use of safe and unsafe
+--   foreign calls.
+--
+--   The functions here are named in a similar fashion to the original Blas interface, with
+--   the type-dependent letter(s) removed.  Some functions have been merged with
+--   others to allow the interface to work on both real and complex numbers.  If you can't a
+--   particular function, try looking for its corresponding complex equivalent (e.g.
+--   @symv@ is a special case of 'hemv' applied to real numbers).
+--
+--   Note: although complex versions of 'rot' and 'rotg' exist in many implementations,
+--   they are not part of the official Blas standard and therefore not included here.  If
+--   you /really/ need them, submit a ticket so we can try to come up with a solution.
+--
+--   The documentation here is still incomplete.  Consult the
+--   <http://netlib.org/blas/#_blas_routines official documentation> for more
+--   information.
+--
+--   Notation:
+--
+--     * @⋅@ denotes dot product (without any conjugation).
+--     * @*@ denotes complex conjugation.
+--     * @⊤@ denotes transpose.
+--     * @†@ denotes conjugate transpose (Hermitian conjugate).
+--
+--   Conventions:
+--
+--     * All scalars are denoted with lowercase Greek letters
+--     * All vectors are denoted with lowercase Latin letters and are
+--       assumed to be column vectors (unless transposed).
+--     * All matrices are denoted with uppercase Latin letters.
+--
+--   /Since: 0.1.1/
+module Blas.Specialized.ComplexFloat.Unsafe (
+  -- * Level 1: vector-vector operations
+  -- ** Basic operations
+    swap
+  , scal
+  , copy
+  , axpy
+  , dotu
+  , dotc
+  -- ** Norm operations
+  , nrm2
+  , asum
+  , iamax
+  -- * Level 2: matrix-vector operations
+  -- ** Multiplication
+  , gemv
+  , gbmv
+  , hemv
+  , hbmv
+  , hpmv
+  -- ** Triangular operations
+  , trmv
+  , tbmv
+  , tpmv
+  , trsv
+  , tbsv
+  , tpsv
+  -- ** Rank updates
+  , geru
+  , gerc
+  , her
+  , hpr
+  , her2
+  , hpr2
+  -- * Level 3: matrix-matrix operations
+  -- ** Multiplication
+  , gemm
+  , symm
+  , hemm
+  -- ** Rank updates
+  , syrk
+  , herk
+  , syr2k
+  , her2k
+  -- ** Triangular operations
+  , trmm
+  , trsm
+  ) where
+import Foreign (Ptr)
+import Data.Complex (Complex((:+)))
+import FFI (getReturnValue)
+import Blas.Primitive.Types (Order, Transpose, Uplo, Diag, Side)
+import qualified Blas.Primitive.Unsafe as C
+
+-- | Swap two vectors:
+--
+--   > (x, y) ← (y, x)
+swap :: Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+swap = C.cswap
+
+
+-- | Multiply a vector by a scalar.
+--
+--   > x ← α x
+scal :: Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+scal n (alpha :+ 0) = C.csscal n alpha
+scal n alpha = C.cscal n alpha
+
+
+-- | Copy a vector into another vector:
+--
+--   > y ← x
+copy :: Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+copy = C.ccopy
+
+
+-- | Add a scalar-vector product to a vector.
+--
+--   > y ← α x + y
+axpy :: Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+axpy = C.caxpy
+
+
+-- | Calculate the bilinear dot product of two vectors:
+--
+--   > x ⋅ y ≡ ∑[i] x[i] y[i]
+dotu :: Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO (Complex Float)
+dotu a b c d e = getReturnValue (C.cdotu_sub a b c d e)
+
+
+-- | Calculate the sesquilinear dot product of two vectors.
+--
+--   > x* ⋅ y ≡ ∑[i] x[i]* y[i]
+dotc :: Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO (Complex Float)
+dotc a b c d e = getReturnValue (C.cdotc_sub a b c d e)
+
+
+-- | Calculate the Euclidean (L²) norm of a vector:
+--
+--   > ‖x‖₂ ≡ √(∑[i] x[i]²)
+nrm2 :: Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO Float
+nrm2 = C.scnrm2
+
+
+-- | Calculate the Manhattan (L¹) norm, equal to the sum of the magnitudes of the elements:
+--
+--   > ‖x‖₁ = ∑[i] |x[i]|
+asum :: Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO Float
+asum = C.scasum
+
+
+-- | Calculate the index of the element with the maximum magnitude (absolute value).
+iamax :: Int
+      -> Ptr (Complex Float)
+      -> Int
+      -> IO Int
+iamax = C.icamax
+
+
+-- | Perform a general matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gemv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+gemv = C.cgemv
+
+
+-- | Perform a general banded matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gbmv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+gbmv = C.cgbmv
+
+
+-- | Perform a hermitian matrix-vector update.
+--
+--   > y ← α A x + β y
+hemv :: Order
+     -> Uplo
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+hemv = C.chemv
+
+
+-- | Perform a hermitian banded matrix-vector update.
+--
+--   > y ← α A x + β y
+hbmv :: Order
+     -> Uplo
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+hbmv = C.chbmv
+
+
+-- | Perform a hermitian packed matrix-vector update.
+--
+--   > y ← α A x + β y
+hpmv :: Order
+     -> Uplo
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Ptr (Complex Float)
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+hpmv = C.chpmv
+
+
+-- | Multiply a triangular matrix by a vector.
+--
+--   > x ← T(A) x
+trmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+trmv = C.ctrmv
+
+
+-- | Multiply a triangular banded matrix by a vector.
+--
+--   > x ← T(A) x
+tbmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+tbmv = C.ctbmv
+
+
+-- | Multiply a triangular packed matrix by a vector.
+--
+--   > x ← T(A) x
+tpmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Float)
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+tpmv = C.ctpmv
+
+
+-- | Multiply an inverse triangular matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+trsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+trsv = C.ctrsv
+
+
+-- | Multiply an inverse triangular banded matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tbsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+tbsv = C.ctbsv
+
+
+-- | Multiply an inverse triangular packed matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tpsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr (Complex Float)
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+tpsv = C.ctpsv
+
+
+-- | Perform an unconjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y⊤ + A
+geru :: Order
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+geru = C.cgeru
+
+
+-- | Perform a conjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y† + A
+gerc :: Order
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+gerc = C.cgerc
+
+
+-- | Perform a rank-1 update of a Hermitian matrix.
+--
+--   > A ← α x y† + A
+her :: Order
+    -> Uplo
+    -> Int
+    -> Float
+    -> Ptr (Complex Float)
+    -> Int
+    -> Ptr (Complex Float)
+    -> Int
+    -> IO ()
+her = C.cher
+
+
+-- | Perform a rank-1 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + A
+hpr :: Order
+    -> Uplo
+    -> Int
+    -> Float
+    -> Ptr (Complex Float)
+    -> Int
+    -> Ptr (Complex Float)
+    -> IO ()
+hpr = C.chpr
+
+
+-- | Perform a rank-2 update of a Hermitian matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+her2 :: Order
+     -> Uplo
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+her2 = C.cher2
+
+
+-- | Perform a rank-2 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+hpr2 :: Order
+     -> Uplo
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> IO ()
+hpr2 = C.chpr2
+
+
+-- | Perform a general matrix-matrix update.
+--
+--   > C ← α T(A) U(B) + β C
+gemm :: Order -- ^ Layout of all the matrices.
+     -> Transpose -- ^ The operation @T@ to be applied to @A@.
+     -> Transpose -- ^ The operation @U@ to be applied to @B@.
+     -> Int -- ^ Number of rows of @T(A)@ and @C@.
+     -> Int -- ^ Number of columns of @U(B)@ and @C@.
+     -> Int -- ^ Number of columns of @T(A)@ and number of rows of @U(B)@.
+     -> Complex Float -- ^ Scaling factor @α@ of the product.
+     -> Ptr (Complex Float) -- ^ Pointer to a matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr (Complex Float) -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Complex Float -- ^ Scaling factor @β@ of the original @C@.
+     -> Ptr (Complex Float) -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+gemm = C.cgemm
+
+
+-- | Perform a symmetric matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is symmetric.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+symm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Complex Float -- ^ Scaling factor @α@ of the product.
+     -> Ptr (Complex Float) -- ^ Pointer to a symmetric matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr (Complex Float) -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Complex Float -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr (Complex Float) -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+symm = C.csymm
+
+
+-- | Perform a Hermitian matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is Hermitian.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+hemm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Complex Float -- ^ Scaling factor @α@ of the product.
+     -> Ptr (Complex Float) -- ^ Pointer to a Hermitian matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr (Complex Float) -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Complex Float -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr (Complex Float) -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+hemm = C.chemm
+
+
+-- | Perform a symmetric rank-k update.
+--
+--   > C ← α A A⊤ + β C    or    C ← α A⊤ A + β C
+syrk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+syrk = C.csyrk
+
+
+-- | Perform a Hermitian rank-k update.
+--
+--   > C ← α A A† + β C    or    C ← α A† A + β C
+herk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+herk = C.cherk
+
+
+-- | Perform a symmetric rank-2k update.
+--
+--   > C ← α A B⊤ + α* B A⊤ + β C    or    C ← α A⊤ B + α* B⊤ A + β C
+syr2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Complex Float
+      -> Ptr (Complex Float)
+      -> Int
+      -> Ptr (Complex Float)
+      -> Int
+      -> Complex Float
+      -> Ptr (Complex Float)
+      -> Int
+      -> IO ()
+syr2k = C.csyr2k
+
+
+-- | Perform a Hermitian rank-2k update.
+--
+--   > C ← α A B† + α* B A† + β C    or    C ← α A† B + α* B† A + β C
+her2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Complex Float
+      -> Ptr (Complex Float)
+      -> Int
+      -> Ptr (Complex Float)
+      -> Int
+      -> Float
+      -> Ptr (Complex Float)
+      -> Int
+      -> IO ()
+her2k = C.cher2k
+
+
+-- | Perform a triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A) B    or    B ← α B T(A)
+--
+--   where @A@ is triangular.
+trmm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+trmm = C.ctrmm
+
+
+-- | Perform an inverse triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A⁻¹) B    or    B ← α B T(A⁻¹)
+--
+--   where @A@ is triangular.
+trsm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Complex Float
+     -> Ptr (Complex Float)
+     -> Int
+     -> Ptr (Complex Float)
+     -> Int
+     -> IO ()
+trsm = C.ctrsm
diff --git a/src/Blas/Specialized/Double/Safe.hs b/src/Blas/Specialized/Double/Safe.hs
new file mode 100644
--- /dev/null
+++ b/src/Blas/Specialized/Double/Safe.hs
@@ -0,0 +1,718 @@
+-- This file is auto-generated.  Do not edit directly.
+-- |
+--   Stability: Experimental
+--
+--   Generic interface to Blas using safe foreign calls.  Refer to the GHC documentation
+--   for more information regarding appropriate use of safe and unsafe foreign calls.
+--
+--   The functions here are named in a similar fashion to the original Blas interface, with
+--   the type-dependent letter(s) removed.  Some functions have been merged with
+--   others to allow the interface to work on both real and complex numbers.  If you can't a
+--   particular function, try looking for its corresponding complex equivalent (e.g.
+--   @symv@ is a special case of 'hemv' applied to real numbers).
+--
+--   Note: although complex versions of 'rot' and 'rotg' exist in many implementations,
+--   they are not part of the official Blas standard and therefore not included here.  If
+--   you /really/ need them, submit a ticket so we can try to come up with a solution.
+--
+--   The documentation here is still incomplete.  Consult the
+--   <http://netlib.org/blas/#_blas_routines official documentation> for more
+--   information.
+--
+--   Notation:
+--
+--     * @⋅@ denotes dot product (without any conjugation).
+--     * @*@ denotes complex conjugation.
+--     * @⊤@ denotes transpose.
+--     * @†@ denotes conjugate transpose (Hermitian conjugate).
+--
+--   Conventions:
+--
+--     * All scalars are denoted with lowercase Greek letters
+--     * All vectors are denoted with lowercase Latin letters and are
+--       assumed to be column vectors (unless transposed).
+--     * All matrices are denoted with uppercase Latin letters.
+--
+--   /Since: 0.1.1/
+module Blas.Specialized.Double.Safe (
+  -- * Level 1: vector-vector operations
+  -- ** Givens rotations
+    rotg
+  , rotmg
+  , rot
+  , rotm
+  -- ** Basic operations
+  , swap
+  , scal
+  , copy
+  , axpy
+  , dotu
+  , dotc
+  , dsdot
+  -- ** Norm operations
+  , nrm2
+  , asum
+  , iamax
+  -- * Level 2: matrix-vector operations
+  -- ** Multiplication
+  , gemv
+  , gbmv
+  , hemv
+  , hbmv
+  , hpmv
+  -- ** Triangular operations
+  , trmv
+  , tbmv
+  , tpmv
+  , trsv
+  , tbsv
+  , tpsv
+  -- ** Rank updates
+  , geru
+  , gerc
+  , her
+  , hpr
+  , her2
+  , hpr2
+  -- * Level 3: matrix-matrix operations
+  -- ** Multiplication
+  , gemm
+  , symm
+  , hemm
+  -- ** Rank updates
+  , syrk
+  , herk
+  , syr2k
+  , her2k
+  -- ** Triangular operations
+  , trmm
+  , trsm
+  ) where
+import Foreign (Ptr)
+import Blas.Primitive.Types (Order, Transpose, Uplo, Diag, Side)
+import qualified Blas.Primitive.Safe as C
+
+-- | Generate a Givens rotation. (Only available for real floating-point types.)
+rotg :: Ptr Double
+     -> Ptr Double
+     -> Ptr Double
+     -> Ptr Double
+     -> IO ()
+rotg = C.drotg
+
+
+-- | Generate a modified Givens rotation. (Only available for real floating-point
+--   types.)
+rotmg :: Ptr Double
+      -> Ptr Double
+      -> Ptr Double
+      -> Double
+      -> Ptr Double
+      -> IO ()
+rotmg = C.drotmg
+
+
+-- | Apply a Givens rotation. (Only available for real floating-point types.)
+rot :: Int
+    -> Ptr Double
+    -> Int
+    -> Ptr Double
+    -> Int
+    -> Double
+    -> Double
+    -> IO ()
+rot = C.drot
+
+
+-- | Apply a modified Givens rotation. (Only available for real floating-point types.)
+rotm :: Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> IO ()
+rotm = C.drotm
+
+
+-- | Swap two vectors:
+--
+--   > (x, y) ← (y, x)
+swap :: Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+swap = C.dswap
+
+
+-- | Multiply a vector by a scalar.
+--
+--   > x ← α x
+scal :: Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+scal = C.dscal
+
+
+-- | Copy a vector into another vector:
+--
+--   > y ← x
+copy :: Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+copy = C.dcopy
+
+
+-- | Add a scalar-vector product to a vector.
+--
+--   > y ← α x + y
+axpy :: Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+axpy = C.daxpy
+
+
+-- | Calculate the bilinear dot product of two vectors:
+--
+--   > x ⋅ y ≡ ∑[i] x[i] y[i]
+dotu :: Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO Double
+dotu = C.ddot
+
+
+-- | Calculate the sesquilinear dot product of two vectors.
+--
+--   > x* ⋅ y ≡ ∑[i] x[i]* y[i]
+dotc :: Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO Double
+dotc = C.ddot
+
+
+-- | Calculate the dot product of two vectors with extended precision accumulation of the
+--   intermediate results and return a double-precision result.  (Only available in
+--   the @Double@ module.)
+dsdot :: Int
+      -> Ptr Float
+      -> Int
+      -> Ptr Float
+      -> Int
+      -> IO Double
+dsdot = C.dsdot
+
+
+-- | Calculate the Euclidean (L²) norm of a vector:
+--
+--   > ‖x‖₂ ≡ √(∑[i] x[i]²)
+nrm2 :: Int
+     -> Ptr Double
+     -> Int
+     -> IO Double
+nrm2 = C.dnrm2
+
+
+-- | Calculate the Manhattan (L¹) norm, equal to the sum of the magnitudes of the elements:
+--
+--   > ‖x‖₁ = ∑[i] |x[i]|
+asum :: Int
+     -> Ptr Double
+     -> Int
+     -> IO Double
+asum = C.dasum
+
+
+-- | Calculate the index of the element with the maximum magnitude (absolute value).
+iamax :: Int
+      -> Ptr Double
+      -> Int
+      -> IO Int
+iamax = C.idamax
+
+
+-- | Perform a general matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gemv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+gemv = C.dgemv
+
+
+-- | Perform a general banded matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gbmv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+gbmv = C.dgbmv
+
+
+-- | Perform a hermitian matrix-vector update.
+--
+--   > y ← α A x + β y
+hemv :: Order
+     -> Uplo
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+hemv = C.dsymv
+
+
+-- | Perform a hermitian banded matrix-vector update.
+--
+--   > y ← α A x + β y
+hbmv :: Order
+     -> Uplo
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+hbmv = C.dsbmv
+
+
+-- | Perform a hermitian packed matrix-vector update.
+--
+--   > y ← α A x + β y
+hpmv :: Order
+     -> Uplo
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+hpmv = C.dspmv
+
+
+-- | Multiply a triangular matrix by a vector.
+--
+--   > x ← T(A) x
+trmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+trmv = C.dtrmv
+
+
+-- | Multiply a triangular banded matrix by a vector.
+--
+--   > x ← T(A) x
+tbmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+tbmv = C.dtbmv
+
+
+-- | Multiply a triangular packed matrix by a vector.
+--
+--   > x ← T(A) x
+tpmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+tpmv = C.dtpmv
+
+
+-- | Multiply an inverse triangular matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+trsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+trsv = C.dtrsv
+
+
+-- | Multiply an inverse triangular banded matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tbsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+tbsv = C.dtbsv
+
+
+-- | Multiply an inverse triangular packed matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tpsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+tpsv = C.dtpsv
+
+
+-- | Perform an unconjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y⊤ + A
+geru :: Order
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+geru = C.dger
+
+
+-- | Perform a conjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y† + A
+gerc :: Order
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+gerc = C.dger
+
+
+-- | Perform a rank-1 update of a Hermitian matrix.
+--
+--   > A ← α x y† + A
+her :: Order
+    -> Uplo
+    -> Int
+    -> Double
+    -> Ptr Double
+    -> Int
+    -> Ptr Double
+    -> Int
+    -> IO ()
+her = C.dsyr
+
+
+-- | Perform a rank-1 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + A
+hpr :: Order
+    -> Uplo
+    -> Int
+    -> Double
+    -> Ptr Double
+    -> Int
+    -> Ptr Double
+    -> IO ()
+hpr = C.dspr
+
+
+-- | Perform a rank-2 update of a Hermitian matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+her2 :: Order
+     -> Uplo
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+her2 = C.dsyr2
+
+
+-- | Perform a rank-2 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+hpr2 :: Order
+     -> Uplo
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> IO ()
+hpr2 = C.dspr2
+
+
+-- | Perform a general matrix-matrix update.
+--
+--   > C ← α T(A) U(B) + β C
+gemm :: Order -- ^ Layout of all the matrices.
+     -> Transpose -- ^ The operation @T@ to be applied to @A@.
+     -> Transpose -- ^ The operation @U@ to be applied to @B@.
+     -> Int -- ^ Number of rows of @T(A)@ and @C@.
+     -> Int -- ^ Number of columns of @U(B)@ and @C@.
+     -> Int -- ^ Number of columns of @T(A)@ and number of rows of @U(B)@.
+     -> Double -- ^ Scaling factor @α@ of the product.
+     -> Ptr Double -- ^ Pointer to a matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr Double -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Double -- ^ Scaling factor @β@ of the original @C@.
+     -> Ptr Double -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+gemm = C.dgemm
+
+
+-- | Perform a symmetric matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is symmetric.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+symm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Double -- ^ Scaling factor @α@ of the product.
+     -> Ptr Double -- ^ Pointer to a symmetric matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr Double -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Double -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr Double -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+symm = C.dsymm
+
+
+-- | Perform a Hermitian matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is Hermitian.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+hemm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Double -- ^ Scaling factor @α@ of the product.
+     -> Ptr Double -- ^ Pointer to a Hermitian matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr Double -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Double -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr Double -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+hemm = C.dsymm
+
+
+-- | Perform a symmetric rank-k update.
+--
+--   > C ← α A A⊤ + β C    or    C ← α A⊤ A + β C
+syrk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+syrk = C.dsyrk
+
+
+-- | Perform a Hermitian rank-k update.
+--
+--   > C ← α A A† + β C    or    C ← α A† A + β C
+herk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+herk = C.dsyrk
+
+
+-- | Perform a symmetric rank-2k update.
+--
+--   > C ← α A B⊤ + α* B A⊤ + β C    or    C ← α A⊤ B + α* B⊤ A + β C
+syr2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Double
+      -> Ptr Double
+      -> Int
+      -> Ptr Double
+      -> Int
+      -> Double
+      -> Ptr Double
+      -> Int
+      -> IO ()
+syr2k = C.dsyr2k
+
+
+-- | Perform a Hermitian rank-2k update.
+--
+--   > C ← α A B† + α* B A† + β C    or    C ← α A† B + α* B† A + β C
+her2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Double
+      -> Ptr Double
+      -> Int
+      -> Ptr Double
+      -> Int
+      -> Double
+      -> Ptr Double
+      -> Int
+      -> IO ()
+her2k = C.dsyr2k
+
+
+-- | Perform a triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A) B    or    B ← α B T(A)
+--
+--   where @A@ is triangular.
+trmm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+trmm = C.dtrmm
+
+
+-- | Perform an inverse triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A⁻¹) B    or    B ← α B T(A⁻¹)
+--
+--   where @A@ is triangular.
+trsm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+trsm = C.dtrsm
diff --git a/src/Blas/Specialized/Double/Unsafe.hs b/src/Blas/Specialized/Double/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/src/Blas/Specialized/Double/Unsafe.hs
@@ -0,0 +1,719 @@
+-- This file is auto-generated.  Do not edit directly.
+-- |
+--   Stability: Experimental
+--
+--   Generic interface to Blas using unsafe foreign calls.  Refer to the GHC
+--   documentation for more information regarding appropriate use of safe and unsafe
+--   foreign calls.
+--
+--   The functions here are named in a similar fashion to the original Blas interface, with
+--   the type-dependent letter(s) removed.  Some functions have been merged with
+--   others to allow the interface to work on both real and complex numbers.  If you can't a
+--   particular function, try looking for its corresponding complex equivalent (e.g.
+--   @symv@ is a special case of 'hemv' applied to real numbers).
+--
+--   Note: although complex versions of 'rot' and 'rotg' exist in many implementations,
+--   they are not part of the official Blas standard and therefore not included here.  If
+--   you /really/ need them, submit a ticket so we can try to come up with a solution.
+--
+--   The documentation here is still incomplete.  Consult the
+--   <http://netlib.org/blas/#_blas_routines official documentation> for more
+--   information.
+--
+--   Notation:
+--
+--     * @⋅@ denotes dot product (without any conjugation).
+--     * @*@ denotes complex conjugation.
+--     * @⊤@ denotes transpose.
+--     * @†@ denotes conjugate transpose (Hermitian conjugate).
+--
+--   Conventions:
+--
+--     * All scalars are denoted with lowercase Greek letters
+--     * All vectors are denoted with lowercase Latin letters and are
+--       assumed to be column vectors (unless transposed).
+--     * All matrices are denoted with uppercase Latin letters.
+--
+--   /Since: 0.1.1/
+module Blas.Specialized.Double.Unsafe (
+  -- * Level 1: vector-vector operations
+  -- ** Givens rotations
+    rotg
+  , rotmg
+  , rot
+  , rotm
+  -- ** Basic operations
+  , swap
+  , scal
+  , copy
+  , axpy
+  , dotu
+  , dotc
+  , dsdot
+  -- ** Norm operations
+  , nrm2
+  , asum
+  , iamax
+  -- * Level 2: matrix-vector operations
+  -- ** Multiplication
+  , gemv
+  , gbmv
+  , hemv
+  , hbmv
+  , hpmv
+  -- ** Triangular operations
+  , trmv
+  , tbmv
+  , tpmv
+  , trsv
+  , tbsv
+  , tpsv
+  -- ** Rank updates
+  , geru
+  , gerc
+  , her
+  , hpr
+  , her2
+  , hpr2
+  -- * Level 3: matrix-matrix operations
+  -- ** Multiplication
+  , gemm
+  , symm
+  , hemm
+  -- ** Rank updates
+  , syrk
+  , herk
+  , syr2k
+  , her2k
+  -- ** Triangular operations
+  , trmm
+  , trsm
+  ) where
+import Foreign (Ptr)
+import Blas.Primitive.Types (Order, Transpose, Uplo, Diag, Side)
+import qualified Blas.Primitive.Unsafe as C
+
+-- | Generate a Givens rotation. (Only available for real floating-point types.)
+rotg :: Ptr Double
+     -> Ptr Double
+     -> Ptr Double
+     -> Ptr Double
+     -> IO ()
+rotg = C.drotg
+
+
+-- | Generate a modified Givens rotation. (Only available for real floating-point
+--   types.)
+rotmg :: Ptr Double
+      -> Ptr Double
+      -> Ptr Double
+      -> Double
+      -> Ptr Double
+      -> IO ()
+rotmg = C.drotmg
+
+
+-- | Apply a Givens rotation. (Only available for real floating-point types.)
+rot :: Int
+    -> Ptr Double
+    -> Int
+    -> Ptr Double
+    -> Int
+    -> Double
+    -> Double
+    -> IO ()
+rot = C.drot
+
+
+-- | Apply a modified Givens rotation. (Only available for real floating-point types.)
+rotm :: Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> IO ()
+rotm = C.drotm
+
+
+-- | Swap two vectors:
+--
+--   > (x, y) ← (y, x)
+swap :: Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+swap = C.dswap
+
+
+-- | Multiply a vector by a scalar.
+--
+--   > x ← α x
+scal :: Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+scal = C.dscal
+
+
+-- | Copy a vector into another vector:
+--
+--   > y ← x
+copy :: Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+copy = C.dcopy
+
+
+-- | Add a scalar-vector product to a vector.
+--
+--   > y ← α x + y
+axpy :: Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+axpy = C.daxpy
+
+
+-- | Calculate the bilinear dot product of two vectors:
+--
+--   > x ⋅ y ≡ ∑[i] x[i] y[i]
+dotu :: Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO Double
+dotu = C.ddot
+
+
+-- | Calculate the sesquilinear dot product of two vectors.
+--
+--   > x* ⋅ y ≡ ∑[i] x[i]* y[i]
+dotc :: Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO Double
+dotc = C.ddot
+
+
+-- | Calculate the dot product of two vectors with extended precision accumulation of the
+--   intermediate results and return a double-precision result.  (Only available in
+--   the @Double@ module.)
+dsdot :: Int
+      -> Ptr Float
+      -> Int
+      -> Ptr Float
+      -> Int
+      -> IO Double
+dsdot = C.dsdot
+
+
+-- | Calculate the Euclidean (L²) norm of a vector:
+--
+--   > ‖x‖₂ ≡ √(∑[i] x[i]²)
+nrm2 :: Int
+     -> Ptr Double
+     -> Int
+     -> IO Double
+nrm2 = C.dnrm2
+
+
+-- | Calculate the Manhattan (L¹) norm, equal to the sum of the magnitudes of the elements:
+--
+--   > ‖x‖₁ = ∑[i] |x[i]|
+asum :: Int
+     -> Ptr Double
+     -> Int
+     -> IO Double
+asum = C.dasum
+
+
+-- | Calculate the index of the element with the maximum magnitude (absolute value).
+iamax :: Int
+      -> Ptr Double
+      -> Int
+      -> IO Int
+iamax = C.idamax
+
+
+-- | Perform a general matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gemv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+gemv = C.dgemv
+
+
+-- | Perform a general banded matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gbmv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+gbmv = C.dgbmv
+
+
+-- | Perform a hermitian matrix-vector update.
+--
+--   > y ← α A x + β y
+hemv :: Order
+     -> Uplo
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+hemv = C.dsymv
+
+
+-- | Perform a hermitian banded matrix-vector update.
+--
+--   > y ← α A x + β y
+hbmv :: Order
+     -> Uplo
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+hbmv = C.dsbmv
+
+
+-- | Perform a hermitian packed matrix-vector update.
+--
+--   > y ← α A x + β y
+hpmv :: Order
+     -> Uplo
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+hpmv = C.dspmv
+
+
+-- | Multiply a triangular matrix by a vector.
+--
+--   > x ← T(A) x
+trmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+trmv = C.dtrmv
+
+
+-- | Multiply a triangular banded matrix by a vector.
+--
+--   > x ← T(A) x
+tbmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+tbmv = C.dtbmv
+
+
+-- | Multiply a triangular packed matrix by a vector.
+--
+--   > x ← T(A) x
+tpmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+tpmv = C.dtpmv
+
+
+-- | Multiply an inverse triangular matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+trsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+trsv = C.dtrsv
+
+
+-- | Multiply an inverse triangular banded matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tbsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+tbsv = C.dtbsv
+
+
+-- | Multiply an inverse triangular packed matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tpsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+tpsv = C.dtpsv
+
+
+-- | Perform an unconjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y⊤ + A
+geru :: Order
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+geru = C.dger
+
+
+-- | Perform a conjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y† + A
+gerc :: Order
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+gerc = C.dger
+
+
+-- | Perform a rank-1 update of a Hermitian matrix.
+--
+--   > A ← α x y† + A
+her :: Order
+    -> Uplo
+    -> Int
+    -> Double
+    -> Ptr Double
+    -> Int
+    -> Ptr Double
+    -> Int
+    -> IO ()
+her = C.dsyr
+
+
+-- | Perform a rank-1 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + A
+hpr :: Order
+    -> Uplo
+    -> Int
+    -> Double
+    -> Ptr Double
+    -> Int
+    -> Ptr Double
+    -> IO ()
+hpr = C.dspr
+
+
+-- | Perform a rank-2 update of a Hermitian matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+her2 :: Order
+     -> Uplo
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+her2 = C.dsyr2
+
+
+-- | Perform a rank-2 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+hpr2 :: Order
+     -> Uplo
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> IO ()
+hpr2 = C.dspr2
+
+
+-- | Perform a general matrix-matrix update.
+--
+--   > C ← α T(A) U(B) + β C
+gemm :: Order -- ^ Layout of all the matrices.
+     -> Transpose -- ^ The operation @T@ to be applied to @A@.
+     -> Transpose -- ^ The operation @U@ to be applied to @B@.
+     -> Int -- ^ Number of rows of @T(A)@ and @C@.
+     -> Int -- ^ Number of columns of @U(B)@ and @C@.
+     -> Int -- ^ Number of columns of @T(A)@ and number of rows of @U(B)@.
+     -> Double -- ^ Scaling factor @α@ of the product.
+     -> Ptr Double -- ^ Pointer to a matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr Double -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Double -- ^ Scaling factor @β@ of the original @C@.
+     -> Ptr Double -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+gemm = C.dgemm
+
+
+-- | Perform a symmetric matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is symmetric.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+symm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Double -- ^ Scaling factor @α@ of the product.
+     -> Ptr Double -- ^ Pointer to a symmetric matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr Double -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Double -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr Double -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+symm = C.dsymm
+
+
+-- | Perform a Hermitian matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is Hermitian.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+hemm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Double -- ^ Scaling factor @α@ of the product.
+     -> Ptr Double -- ^ Pointer to a Hermitian matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr Double -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Double -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr Double -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+hemm = C.dsymm
+
+
+-- | Perform a symmetric rank-k update.
+--
+--   > C ← α A A⊤ + β C    or    C ← α A⊤ A + β C
+syrk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+syrk = C.dsyrk
+
+
+-- | Perform a Hermitian rank-k update.
+--
+--   > C ← α A A† + β C    or    C ← α A† A + β C
+herk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> IO ()
+herk = C.dsyrk
+
+
+-- | Perform a symmetric rank-2k update.
+--
+--   > C ← α A B⊤ + α* B A⊤ + β C    or    C ← α A⊤ B + α* B⊤ A + β C
+syr2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Double
+      -> Ptr Double
+      -> Int
+      -> Ptr Double
+      -> Int
+      -> Double
+      -> Ptr Double
+      -> Int
+      -> IO ()
+syr2k = C.dsyr2k
+
+
+-- | Perform a Hermitian rank-2k update.
+--
+--   > C ← α A B† + α* B A† + β C    or    C ← α A† B + α* B† A + β C
+her2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Double
+      -> Ptr Double
+      -> Int
+      -> Ptr Double
+      -> Int
+      -> Double
+      -> Ptr Double
+      -> Int
+      -> IO ()
+her2k = C.dsyr2k
+
+
+-- | Perform a triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A) B    or    B ← α B T(A)
+--
+--   where @A@ is triangular.
+trmm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+trmm = C.dtrmm
+
+
+-- | Perform an inverse triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A⁻¹) B    or    B ← α B T(A⁻¹)
+--
+--   where @A@ is triangular.
+trsm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Double
+     -> Ptr Double
+     -> Int
+     -> Ptr Double
+     -> Int
+     -> IO ()
+trsm = C.dtrsm
diff --git a/src/Blas/Specialized/Float/Safe.hs b/src/Blas/Specialized/Float/Safe.hs
new file mode 100644
--- /dev/null
+++ b/src/Blas/Specialized/Float/Safe.hs
@@ -0,0 +1,719 @@
+-- This file is auto-generated.  Do not edit directly.
+-- |
+--   Stability: Experimental
+--
+--   Generic interface to Blas using safe foreign calls.  Refer to the GHC documentation
+--   for more information regarding appropriate use of safe and unsafe foreign calls.
+--
+--   The functions here are named in a similar fashion to the original Blas interface, with
+--   the type-dependent letter(s) removed.  Some functions have been merged with
+--   others to allow the interface to work on both real and complex numbers.  If you can't a
+--   particular function, try looking for its corresponding complex equivalent (e.g.
+--   @symv@ is a special case of 'hemv' applied to real numbers).
+--
+--   Note: although complex versions of 'rot' and 'rotg' exist in many implementations,
+--   they are not part of the official Blas standard and therefore not included here.  If
+--   you /really/ need them, submit a ticket so we can try to come up with a solution.
+--
+--   The documentation here is still incomplete.  Consult the
+--   <http://netlib.org/blas/#_blas_routines official documentation> for more
+--   information.
+--
+--   Notation:
+--
+--     * @⋅@ denotes dot product (without any conjugation).
+--     * @*@ denotes complex conjugation.
+--     * @⊤@ denotes transpose.
+--     * @†@ denotes conjugate transpose (Hermitian conjugate).
+--
+--   Conventions:
+--
+--     * All scalars are denoted with lowercase Greek letters
+--     * All vectors are denoted with lowercase Latin letters and are
+--       assumed to be column vectors (unless transposed).
+--     * All matrices are denoted with uppercase Latin letters.
+--
+--   /Since: 0.1.1/
+module Blas.Specialized.Float.Safe (
+  -- * Level 1: vector-vector operations
+  -- ** Givens rotations
+    rotg
+  , rotmg
+  , rot
+  , rotm
+  -- ** Basic operations
+  , swap
+  , scal
+  , copy
+  , axpy
+  , dotu
+  , dotc
+  , sdsdot
+  -- ** Norm operations
+  , nrm2
+  , asum
+  , iamax
+  -- * Level 2: matrix-vector operations
+  -- ** Multiplication
+  , gemv
+  , gbmv
+  , hemv
+  , hbmv
+  , hpmv
+  -- ** Triangular operations
+  , trmv
+  , tbmv
+  , tpmv
+  , trsv
+  , tbsv
+  , tpsv
+  -- ** Rank updates
+  , geru
+  , gerc
+  , her
+  , hpr
+  , her2
+  , hpr2
+  -- * Level 3: matrix-matrix operations
+  -- ** Multiplication
+  , gemm
+  , symm
+  , hemm
+  -- ** Rank updates
+  , syrk
+  , herk
+  , syr2k
+  , her2k
+  -- ** Triangular operations
+  , trmm
+  , trsm
+  ) where
+import Foreign (Ptr)
+import Blas.Primitive.Types (Order, Transpose, Uplo, Diag, Side)
+import qualified Blas.Primitive.Safe as C
+
+-- | Generate a Givens rotation. (Only available for real floating-point types.)
+rotg :: Ptr Float
+     -> Ptr Float
+     -> Ptr Float
+     -> Ptr Float
+     -> IO ()
+rotg = C.srotg
+
+
+-- | Generate a modified Givens rotation. (Only available for real floating-point
+--   types.)
+rotmg :: Ptr Float
+      -> Ptr Float
+      -> Ptr Float
+      -> Float
+      -> Ptr Float
+      -> IO ()
+rotmg = C.srotmg
+
+
+-- | Apply a Givens rotation. (Only available for real floating-point types.)
+rot :: Int
+    -> Ptr Float
+    -> Int
+    -> Ptr Float
+    -> Int
+    -> Float
+    -> Float
+    -> IO ()
+rot = C.srot
+
+
+-- | Apply a modified Givens rotation. (Only available for real floating-point types.)
+rotm :: Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> IO ()
+rotm = C.srotm
+
+
+-- | Swap two vectors:
+--
+--   > (x, y) ← (y, x)
+swap :: Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+swap = C.sswap
+
+
+-- | Multiply a vector by a scalar.
+--
+--   > x ← α x
+scal :: Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+scal = C.sscal
+
+
+-- | Copy a vector into another vector:
+--
+--   > y ← x
+copy :: Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+copy = C.scopy
+
+
+-- | Add a scalar-vector product to a vector.
+--
+--   > y ← α x + y
+axpy :: Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+axpy = C.saxpy
+
+
+-- | Calculate the bilinear dot product of two vectors:
+--
+--   > x ⋅ y ≡ ∑[i] x[i] y[i]
+dotu :: Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO Float
+dotu = C.sdot
+
+
+-- | Calculate the sesquilinear dot product of two vectors.
+--
+--   > x* ⋅ y ≡ ∑[i] x[i]* y[i]
+dotc :: Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO Float
+dotc = C.sdot
+
+
+-- | Calculate the dot product of two vectors with extended precision accumulation of the
+--   intermediate results and add a scalar value to the result.  (Only available for the
+--   @'Float'@ type.)
+sdsdot :: Int
+       -> Float
+       -> Ptr Float
+       -> Int
+       -> Ptr Float
+       -> Int
+       -> IO Float
+sdsdot = C.sdsdot
+
+
+-- | Calculate the Euclidean (L²) norm of a vector:
+--
+--   > ‖x‖₂ ≡ √(∑[i] x[i]²)
+nrm2 :: Int
+     -> Ptr Float
+     -> Int
+     -> IO Float
+nrm2 = C.snrm2
+
+
+-- | Calculate the Manhattan (L¹) norm, equal to the sum of the magnitudes of the elements:
+--
+--   > ‖x‖₁ = ∑[i] |x[i]|
+asum :: Int
+     -> Ptr Float
+     -> Int
+     -> IO Float
+asum = C.sasum
+
+
+-- | Calculate the index of the element with the maximum magnitude (absolute value).
+iamax :: Int
+      -> Ptr Float
+      -> Int
+      -> IO Int
+iamax = C.isamax
+
+
+-- | Perform a general matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gemv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+gemv = C.sgemv
+
+
+-- | Perform a general banded matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gbmv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+gbmv = C.sgbmv
+
+
+-- | Perform a hermitian matrix-vector update.
+--
+--   > y ← α A x + β y
+hemv :: Order
+     -> Uplo
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+hemv = C.ssymv
+
+
+-- | Perform a hermitian banded matrix-vector update.
+--
+--   > y ← α A x + β y
+hbmv :: Order
+     -> Uplo
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+hbmv = C.ssbmv
+
+
+-- | Perform a hermitian packed matrix-vector update.
+--
+--   > y ← α A x + β y
+hpmv :: Order
+     -> Uplo
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+hpmv = C.sspmv
+
+
+-- | Multiply a triangular matrix by a vector.
+--
+--   > x ← T(A) x
+trmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+trmv = C.strmv
+
+
+-- | Multiply a triangular banded matrix by a vector.
+--
+--   > x ← T(A) x
+tbmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+tbmv = C.stbmv
+
+
+-- | Multiply a triangular packed matrix by a vector.
+--
+--   > x ← T(A) x
+tpmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+tpmv = C.stpmv
+
+
+-- | Multiply an inverse triangular matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+trsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+trsv = C.strsv
+
+
+-- | Multiply an inverse triangular banded matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tbsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+tbsv = C.stbsv
+
+
+-- | Multiply an inverse triangular packed matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tpsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+tpsv = C.stpsv
+
+
+-- | Perform an unconjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y⊤ + A
+geru :: Order
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+geru = C.sger
+
+
+-- | Perform a conjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y† + A
+gerc :: Order
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+gerc = C.sger
+
+
+-- | Perform a rank-1 update of a Hermitian matrix.
+--
+--   > A ← α x y† + A
+her :: Order
+    -> Uplo
+    -> Int
+    -> Float
+    -> Ptr Float
+    -> Int
+    -> Ptr Float
+    -> Int
+    -> IO ()
+her = C.ssyr
+
+
+-- | Perform a rank-1 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + A
+hpr :: Order
+    -> Uplo
+    -> Int
+    -> Float
+    -> Ptr Float
+    -> Int
+    -> Ptr Float
+    -> IO ()
+hpr = C.sspr
+
+
+-- | Perform a rank-2 update of a Hermitian matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+her2 :: Order
+     -> Uplo
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+her2 = C.ssyr2
+
+
+-- | Perform a rank-2 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+hpr2 :: Order
+     -> Uplo
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> IO ()
+hpr2 = C.sspr2
+
+
+-- | Perform a general matrix-matrix update.
+--
+--   > C ← α T(A) U(B) + β C
+gemm :: Order -- ^ Layout of all the matrices.
+     -> Transpose -- ^ The operation @T@ to be applied to @A@.
+     -> Transpose -- ^ The operation @U@ to be applied to @B@.
+     -> Int -- ^ Number of rows of @T(A)@ and @C@.
+     -> Int -- ^ Number of columns of @U(B)@ and @C@.
+     -> Int -- ^ Number of columns of @T(A)@ and number of rows of @U(B)@.
+     -> Float -- ^ Scaling factor @α@ of the product.
+     -> Ptr Float -- ^ Pointer to a matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr Float -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Float -- ^ Scaling factor @β@ of the original @C@.
+     -> Ptr Float -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+gemm = C.sgemm
+
+
+-- | Perform a symmetric matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is symmetric.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+symm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Float -- ^ Scaling factor @α@ of the product.
+     -> Ptr Float -- ^ Pointer to a symmetric matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr Float -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Float -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr Float -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+symm = C.ssymm
+
+
+-- | Perform a Hermitian matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is Hermitian.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+hemm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Float -- ^ Scaling factor @α@ of the product.
+     -> Ptr Float -- ^ Pointer to a Hermitian matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr Float -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Float -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr Float -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+hemm = C.ssymm
+
+
+-- | Perform a symmetric rank-k update.
+--
+--   > C ← α A A⊤ + β C    or    C ← α A⊤ A + β C
+syrk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+syrk = C.ssyrk
+
+
+-- | Perform a Hermitian rank-k update.
+--
+--   > C ← α A A† + β C    or    C ← α A† A + β C
+herk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+herk = C.ssyrk
+
+
+-- | Perform a symmetric rank-2k update.
+--
+--   > C ← α A B⊤ + α* B A⊤ + β C    or    C ← α A⊤ B + α* B⊤ A + β C
+syr2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Float
+      -> Ptr Float
+      -> Int
+      -> Ptr Float
+      -> Int
+      -> Float
+      -> Ptr Float
+      -> Int
+      -> IO ()
+syr2k = C.ssyr2k
+
+
+-- | Perform a Hermitian rank-2k update.
+--
+--   > C ← α A B† + α* B A† + β C    or    C ← α A† B + α* B† A + β C
+her2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Float
+      -> Ptr Float
+      -> Int
+      -> Ptr Float
+      -> Int
+      -> Float
+      -> Ptr Float
+      -> Int
+      -> IO ()
+her2k = C.ssyr2k
+
+
+-- | Perform a triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A) B    or    B ← α B T(A)
+--
+--   where @A@ is triangular.
+trmm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+trmm = C.strmm
+
+
+-- | Perform an inverse triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A⁻¹) B    or    B ← α B T(A⁻¹)
+--
+--   where @A@ is triangular.
+trsm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+trsm = C.strsm
diff --git a/src/Blas/Specialized/Float/Unsafe.hs b/src/Blas/Specialized/Float/Unsafe.hs
new file mode 100644
--- /dev/null
+++ b/src/Blas/Specialized/Float/Unsafe.hs
@@ -0,0 +1,720 @@
+-- This file is auto-generated.  Do not edit directly.
+-- |
+--   Stability: Experimental
+--
+--   Generic interface to Blas using unsafe foreign calls.  Refer to the GHC
+--   documentation for more information regarding appropriate use of safe and unsafe
+--   foreign calls.
+--
+--   The functions here are named in a similar fashion to the original Blas interface, with
+--   the type-dependent letter(s) removed.  Some functions have been merged with
+--   others to allow the interface to work on both real and complex numbers.  If you can't a
+--   particular function, try looking for its corresponding complex equivalent (e.g.
+--   @symv@ is a special case of 'hemv' applied to real numbers).
+--
+--   Note: although complex versions of 'rot' and 'rotg' exist in many implementations,
+--   they are not part of the official Blas standard and therefore not included here.  If
+--   you /really/ need them, submit a ticket so we can try to come up with a solution.
+--
+--   The documentation here is still incomplete.  Consult the
+--   <http://netlib.org/blas/#_blas_routines official documentation> for more
+--   information.
+--
+--   Notation:
+--
+--     * @⋅@ denotes dot product (without any conjugation).
+--     * @*@ denotes complex conjugation.
+--     * @⊤@ denotes transpose.
+--     * @†@ denotes conjugate transpose (Hermitian conjugate).
+--
+--   Conventions:
+--
+--     * All scalars are denoted with lowercase Greek letters
+--     * All vectors are denoted with lowercase Latin letters and are
+--       assumed to be column vectors (unless transposed).
+--     * All matrices are denoted with uppercase Latin letters.
+--
+--   /Since: 0.1.1/
+module Blas.Specialized.Float.Unsafe (
+  -- * Level 1: vector-vector operations
+  -- ** Givens rotations
+    rotg
+  , rotmg
+  , rot
+  , rotm
+  -- ** Basic operations
+  , swap
+  , scal
+  , copy
+  , axpy
+  , dotu
+  , dotc
+  , sdsdot
+  -- ** Norm operations
+  , nrm2
+  , asum
+  , iamax
+  -- * Level 2: matrix-vector operations
+  -- ** Multiplication
+  , gemv
+  , gbmv
+  , hemv
+  , hbmv
+  , hpmv
+  -- ** Triangular operations
+  , trmv
+  , tbmv
+  , tpmv
+  , trsv
+  , tbsv
+  , tpsv
+  -- ** Rank updates
+  , geru
+  , gerc
+  , her
+  , hpr
+  , her2
+  , hpr2
+  -- * Level 3: matrix-matrix operations
+  -- ** Multiplication
+  , gemm
+  , symm
+  , hemm
+  -- ** Rank updates
+  , syrk
+  , herk
+  , syr2k
+  , her2k
+  -- ** Triangular operations
+  , trmm
+  , trsm
+  ) where
+import Foreign (Ptr)
+import Blas.Primitive.Types (Order, Transpose, Uplo, Diag, Side)
+import qualified Blas.Primitive.Unsafe as C
+
+-- | Generate a Givens rotation. (Only available for real floating-point types.)
+rotg :: Ptr Float
+     -> Ptr Float
+     -> Ptr Float
+     -> Ptr Float
+     -> IO ()
+rotg = C.srotg
+
+
+-- | Generate a modified Givens rotation. (Only available for real floating-point
+--   types.)
+rotmg :: Ptr Float
+      -> Ptr Float
+      -> Ptr Float
+      -> Float
+      -> Ptr Float
+      -> IO ()
+rotmg = C.srotmg
+
+
+-- | Apply a Givens rotation. (Only available for real floating-point types.)
+rot :: Int
+    -> Ptr Float
+    -> Int
+    -> Ptr Float
+    -> Int
+    -> Float
+    -> Float
+    -> IO ()
+rot = C.srot
+
+
+-- | Apply a modified Givens rotation. (Only available for real floating-point types.)
+rotm :: Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> IO ()
+rotm = C.srotm
+
+
+-- | Swap two vectors:
+--
+--   > (x, y) ← (y, x)
+swap :: Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+swap = C.sswap
+
+
+-- | Multiply a vector by a scalar.
+--
+--   > x ← α x
+scal :: Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+scal = C.sscal
+
+
+-- | Copy a vector into another vector:
+--
+--   > y ← x
+copy :: Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+copy = C.scopy
+
+
+-- | Add a scalar-vector product to a vector.
+--
+--   > y ← α x + y
+axpy :: Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+axpy = C.saxpy
+
+
+-- | Calculate the bilinear dot product of two vectors:
+--
+--   > x ⋅ y ≡ ∑[i] x[i] y[i]
+dotu :: Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO Float
+dotu = C.sdot
+
+
+-- | Calculate the sesquilinear dot product of two vectors.
+--
+--   > x* ⋅ y ≡ ∑[i] x[i]* y[i]
+dotc :: Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO Float
+dotc = C.sdot
+
+
+-- | Calculate the dot product of two vectors with extended precision accumulation of the
+--   intermediate results and add a scalar value to the result.  (Only available for the
+--   @'Float'@ type.)
+sdsdot :: Int
+       -> Float
+       -> Ptr Float
+       -> Int
+       -> Ptr Float
+       -> Int
+       -> IO Float
+sdsdot = C.sdsdot
+
+
+-- | Calculate the Euclidean (L²) norm of a vector:
+--
+--   > ‖x‖₂ ≡ √(∑[i] x[i]²)
+nrm2 :: Int
+     -> Ptr Float
+     -> Int
+     -> IO Float
+nrm2 = C.snrm2
+
+
+-- | Calculate the Manhattan (L¹) norm, equal to the sum of the magnitudes of the elements:
+--
+--   > ‖x‖₁ = ∑[i] |x[i]|
+asum :: Int
+     -> Ptr Float
+     -> Int
+     -> IO Float
+asum = C.sasum
+
+
+-- | Calculate the index of the element with the maximum magnitude (absolute value).
+iamax :: Int
+      -> Ptr Float
+      -> Int
+      -> IO Int
+iamax = C.isamax
+
+
+-- | Perform a general matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gemv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+gemv = C.sgemv
+
+
+-- | Perform a general banded matrix-vector update.
+--
+--   > y ← α T(A) x + β y
+gbmv :: Order
+     -> Transpose
+     -> Int
+     -> Int
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+gbmv = C.sgbmv
+
+
+-- | Perform a hermitian matrix-vector update.
+--
+--   > y ← α A x + β y
+hemv :: Order
+     -> Uplo
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+hemv = C.ssymv
+
+
+-- | Perform a hermitian banded matrix-vector update.
+--
+--   > y ← α A x + β y
+hbmv :: Order
+     -> Uplo
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+hbmv = C.ssbmv
+
+
+-- | Perform a hermitian packed matrix-vector update.
+--
+--   > y ← α A x + β y
+hpmv :: Order
+     -> Uplo
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+hpmv = C.sspmv
+
+
+-- | Multiply a triangular matrix by a vector.
+--
+--   > x ← T(A) x
+trmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+trmv = C.strmv
+
+
+-- | Multiply a triangular banded matrix by a vector.
+--
+--   > x ← T(A) x
+tbmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+tbmv = C.stbmv
+
+
+-- | Multiply a triangular packed matrix by a vector.
+--
+--   > x ← T(A) x
+tpmv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+tpmv = C.stpmv
+
+
+-- | Multiply an inverse triangular matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+trsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+trsv = C.strsv
+
+
+-- | Multiply an inverse triangular banded matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tbsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+tbsv = C.stbsv
+
+
+-- | Multiply an inverse triangular packed matrix by a vector.
+--
+--   > x ← T(A⁻¹) x
+tpsv :: Order
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Ptr Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+tpsv = C.stpsv
+
+
+-- | Perform an unconjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y⊤ + A
+geru :: Order
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+geru = C.sger
+
+
+-- | Perform a conjugated rank-1 update of a general matrix.
+--
+--   > A ← α x y† + A
+gerc :: Order
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+gerc = C.sger
+
+
+-- | Perform a rank-1 update of a Hermitian matrix.
+--
+--   > A ← α x y† + A
+her :: Order
+    -> Uplo
+    -> Int
+    -> Float
+    -> Ptr Float
+    -> Int
+    -> Ptr Float
+    -> Int
+    -> IO ()
+her = C.ssyr
+
+
+-- | Perform a rank-1 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + A
+hpr :: Order
+    -> Uplo
+    -> Int
+    -> Float
+    -> Ptr Float
+    -> Int
+    -> Ptr Float
+    -> IO ()
+hpr = C.sspr
+
+
+-- | Perform a rank-2 update of a Hermitian matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+her2 :: Order
+     -> Uplo
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+her2 = C.ssyr2
+
+
+-- | Perform a rank-2 update of a Hermitian packed matrix.
+--
+--   > A ← α x y† + y (α x)† + A
+hpr2 :: Order
+     -> Uplo
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> IO ()
+hpr2 = C.sspr2
+
+
+-- | Perform a general matrix-matrix update.
+--
+--   > C ← α T(A) U(B) + β C
+gemm :: Order -- ^ Layout of all the matrices.
+     -> Transpose -- ^ The operation @T@ to be applied to @A@.
+     -> Transpose -- ^ The operation @U@ to be applied to @B@.
+     -> Int -- ^ Number of rows of @T(A)@ and @C@.
+     -> Int -- ^ Number of columns of @U(B)@ and @C@.
+     -> Int -- ^ Number of columns of @T(A)@ and number of rows of @U(B)@.
+     -> Float -- ^ Scaling factor @α@ of the product.
+     -> Ptr Float -- ^ Pointer to a matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr Float -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Float -- ^ Scaling factor @β@ of the original @C@.
+     -> Ptr Float -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+gemm = C.sgemm
+
+
+-- | Perform a symmetric matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is symmetric.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+symm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Float -- ^ Scaling factor @α@ of the product.
+     -> Ptr Float -- ^ Pointer to a symmetric matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr Float -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Float -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr Float -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+symm = C.ssymm
+
+
+-- | Perform a Hermitian matrix-matrix update.
+--
+--   > C ← α A B + β C    or    C ← α B A + β C
+--
+--   where @A@ is Hermitian.  The matrix @A@ must be in an unpacked format, although the
+--   routine will only access half of it as specified by the @'Uplo'@ argument.
+hemm :: Order -- ^ Layout of all the matrices.
+     -> Side -- ^ Side that @A@ appears in the product.
+     -> Uplo -- ^ The part of @A@ that is used.
+     -> Int -- ^ Number of rows of @C@.
+     -> Int -- ^ Number of columns of @C@.
+     -> Float -- ^ Scaling factor @α@ of the product.
+     -> Ptr Float -- ^ Pointer to a Hermitian matrix @A@.
+     -> Int -- ^ Stride of the major dimension of @A@.
+     -> Ptr Float -- ^ Pointer to a matrix @B@.
+     -> Int -- ^ Stride of the major dimension of @B@.
+     -> Float -- ^ Scaling factor @α@ of the original @C@.
+     -> Ptr Float -- ^ Pointer to a mutable matrix @C@.
+     -> Int -- ^ Stride of the major dimension of @C@.
+     -> IO ()
+hemm = C.ssymm
+
+
+-- | Perform a symmetric rank-k update.
+--
+--   > C ← α A A⊤ + β C    or    C ← α A⊤ A + β C
+syrk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+syrk = C.ssyrk
+
+
+-- | Perform a Hermitian rank-k update.
+--
+--   > C ← α A A† + β C    or    C ← α A† A + β C
+herk :: Order
+     -> Uplo
+     -> Transpose
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> IO ()
+herk = C.ssyrk
+
+
+-- | Perform a symmetric rank-2k update.
+--
+--   > C ← α A B⊤ + α* B A⊤ + β C    or    C ← α A⊤ B + α* B⊤ A + β C
+syr2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Float
+      -> Ptr Float
+      -> Int
+      -> Ptr Float
+      -> Int
+      -> Float
+      -> Ptr Float
+      -> Int
+      -> IO ()
+syr2k = C.ssyr2k
+
+
+-- | Perform a Hermitian rank-2k update.
+--
+--   > C ← α A B† + α* B A† + β C    or    C ← α A† B + α* B† A + β C
+her2k :: Order
+      -> Uplo
+      -> Transpose
+      -> Int
+      -> Int
+      -> Float
+      -> Ptr Float
+      -> Int
+      -> Ptr Float
+      -> Int
+      -> Float
+      -> Ptr Float
+      -> Int
+      -> IO ()
+her2k = C.ssyr2k
+
+
+-- | Perform a triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A) B    or    B ← α B T(A)
+--
+--   where @A@ is triangular.
+trmm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+trmm = C.strmm
+
+
+-- | Perform an inverse triangular matrix-matrix multiplication.
+--
+--   > B ← α T(A⁻¹) B    or    B ← α B T(A⁻¹)
+--
+--   where @A@ is triangular.
+trsm :: Order
+     -> Side
+     -> Uplo
+     -> Transpose
+     -> Diag
+     -> Int
+     -> Int
+     -> Float
+     -> Ptr Float
+     -> Int
+     -> Ptr Float
+     -> Int
+     -> IO ()
+trsm = C.strsm
diff --git a/tests/MainTest.hs b/tests/MainTest.hs
--- a/tests/MainTest.hs
+++ b/tests/MainTest.hs
@@ -1,43 +1,18 @@
 {-# LANGUAGE Rank2Types #-}
-module MainTest (tests) where
 import Control.Monad.ST (RealWorld)
 import Data.Complex (Complex)
 import Data.Vector.Storable (MVector(MVector))
-import Distribution.TestSuite
-  ( Progress(Finished)
-  , Result(Fail, Pass)
-  , Test(Test)
-  , TestInstance(TestInstance)
-  )
 import Foreign (Ptr, Storable, withForeignPtr)
 import Text.Printf (printf)
 import Blas.Generic.Unsafe (Numeric)
-import qualified Data.Vector.Generic.Mutable as MVector
 import qualified Data.Vector.Storable as Vector
-import qualified Distribution.TestSuite as Test
 import qualified Blas.Primitive.Types as Blas
 import qualified Blas.Generic.Unsafe as Blas
-
-tests :: IO [Test]
-tests =
-  return $
-  mapNumericTypes (simpleTest "gemm test" . testGemm)
-
-simpleTest :: String -> IO Progress -> Test
-simpleTest name action = Test test
-  where test = TestInstance
-               { Test.run = action
-               , Test.name = name
-               , Test.tags = []
-               , Test.options = []
-               , Test.setOption = \_ _ -> Right test
-               }
-
-passT :: IO Progress
-passT = return $ Finished Pass
+import qualified TestUtils as T
 
-failT :: String -> IO Progress
-failT = return . Finished .Fail
+main :: IO ()
+main = T.runTest $ do
+  sequence_ (mapNumericTypes testGemm)
 
 mapNumericTypes :: (forall a. (Eq a, Numeric a, Show a) => a -> b) -> [b]
 mapNumericTypes f =
@@ -56,7 +31,7 @@
 mVectorFromList :: Storable a => [a] -> IO (MVector RealWorld a)
 mVectorFromList = Vector.thaw . Vector.fromList
 
-testGemm :: (Eq a, Numeric a, Show a) => a -> IO Progress
+testGemm :: (Eq a, Numeric a, Show a) => a -> T.Test ()
 testGemm numType = do
   let order    = Blas.RowMajor
       transa   = Blas.NoTrans
@@ -69,15 +44,15 @@
       b        = Vector.fromList [1, 2, 3, 5]
       expected = Vector.fromList [5, 13, 11, 29]
 
-  c <- mVectorFromList $ take size (repeat 0)
-
-  Vector.unsafeWith a $ \ pa ->
-    Vector.unsafeWith b $ \ pb ->
-      withMVector c $ \ pc ->
-        Blas.gemm order transa transb n n n alpha pa n pb n beta pc n
+  c' <- T.liftIO $ do
+    c <- mVectorFromList $ take size (repeat 0)
+    Vector.unsafeWith a $ \ pa ->
+      Vector.unsafeWith b $ \ pb ->
+        withMVector c $ \ pc ->
+          Blas.gemm order transa transb n n n alpha pa n pb n beta pc n
+    Vector.freeze c
 
-  c' <- Vector.freeze c
   if c' == expected
-    then passT
-    else failT $ printf "result does not match: %s != %s"
-                        (show c') (show expected)
+    then T.passTest "testGemm"
+    else T.failTest $ printf "testGemm: c' does not match: %s != %s"
+                      (show c') (show expected)
diff --git a/tests/TestUtils.hs b/tests/TestUtils.hs
new file mode 100644
--- /dev/null
+++ b/tests/TestUtils.hs
@@ -0,0 +1,78 @@
+module TestUtils where
+import Control.Applicative (Applicative((<*>), pure))
+import System.Exit (exitFailure, exitSuccess)
+import System.IO (hPutStrLn, stderr)
+import Text.Printf (printf)
+
+data TestState
+  = TestState
+    { quiet     :: Bool     -- ^ Whether success messages should be suppressed
+    , failCount :: Int
+    }
+
+initTestState :: TestState
+initTestState
+  = TestState
+    { quiet     = False
+    , failCount = 0
+    }
+
+newtype Test a = Test { runTestM :: TestState -> IO (a, TestState) }
+
+instance Functor Test where
+  fmap f u = return f <*> u
+
+instance Applicative Test where
+  pure      = return
+  mf <*> mx = do
+    f <- mf
+    x <- mx
+    return (f x)
+
+instance Monad Test where
+  return x     = Test $ \ s -> return (x, s)
+  Test f >>= u = Test $ \ s -> do
+    (x, s') <- f s
+    runTestM (u x) s'
+  fail msg     = do
+    failTest "aborted"
+    liftIO (fail msg)
+
+runTest :: Test () -> IO ()
+runTest test = do
+  ((), s) <- runTestM test initTestState
+  if failCount s > 0 then exitFailure else exitSuccess
+
+passTest :: String -> Test ()
+passTest msg = do
+  s <- get
+  if quiet s
+    then return ()
+    else liftIO (putStrLn msg')
+  where msg' = "ok" ++ if null msg then "" else printf " (%s)" msg
+
+failTest :: String -> Test ()
+failTest msg = do
+  liftIO (hPutStrLn stderr ("*** FAIL: " ++ msg))
+  modify $ \ state -> state { failCount = succ (failCount state) }
+
+-- | The test passes only if the boolean argument is true.
+expect :: String -> Bool -> Test ()
+expect msg False = failTest msg
+expect msg True  = passTest msg
+
+liftIO :: IO a -> Test a
+liftIO m = Test $ \ s -> do
+  result <- m
+  return (result, s)
+
+get :: Test TestState
+get = Test $ \ s -> return (s, s)
+
+put :: TestState -> Test ()
+put s = Test $ \ _ -> return ((), s)
+
+modify :: (TestState -> TestState) -> Test ()
+modify f = do
+  s <- get
+  put (f s)
