diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,11 @@
 # Revision history for Z-Data
 
+## 2.0.0.0  -- 2021-12-08
+
+* Work only with GHC >= 9.2, use sized primitive types, new integer types.
+* Remove dependencies on `ghc-prim`, `integer-gmp`, use modules exported by `base` instead. 
+* Change `emptyArr` to a `Arr` class method.
+
 ## 1.1.0.0  -- 2021-07-15
 
 * Fix building issues on ARM platform.
diff --git a/Z-Data.cabal b/Z-Data.cabal
--- a/Z-Data.cabal
+++ b/Z-Data.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               Z-Data
-version:            1.3.0.1
+version:            2.0.0.0
 synopsis:           Array, vector and text
 description:        This package provides array, slice and text operations
 license:            BSD-3-Clause
@@ -112,14 +112,6 @@
   default:     False
   manual:      True
 
-flag integer-simple
-  description:
-    Use the [simple integer library](http://hackage.haskell.org/package/integer-simple)
-    instead of [integer-gmp](http://hackage.haskell.org/package/integer-gmp)
-
-  default:     False
-  manual:      True
-
 flag use-avx2
   description:
     Use AVX2 instructions(utf8 validation, base64 codec, etc).
@@ -187,14 +179,13 @@
     Z.Foreign.CPtr
 
   build-depends:
-    , base                  >=4.12   && <5.0
+    , base                  >=4.16   && <5.0
     , bytestring            >=0.10.4 && <0.12
     , case-insensitive      ^>=1.2
     , containers            ^>=0.6
     , deepseq               ^>=1.4
-    , ghc-prim              >=0.5.3  && <0.8
     , hashable              ^>=1.3
-    , primitive             >=0.7.1  && <0.7.4
+    , primitive             >=0.7.3  && <0.8
     , QuickCheck            >=2.10
     , random                >=1.2.0  && <1.3
     , scientific            >=0.3.7  && <0.4
@@ -311,7 +302,7 @@
     cxx-options:     -DWIN32_LEAN_AND_MEAN -D_WIN32_WINNT=0x0600
   else
     if os(osx)
-      extra-libraries:
+      extra-libraries: 
         c++
         pthread
     else
@@ -319,14 +310,6 @@
         stdc++
         pthread
 
-  if flag(integer-simple)
-    cpp-options:   -DINTEGER_SIMPLE
-    build-depends: integer-simple >=0.1 && <0.5
-
-  else
-    cpp-options:   -DINTEGER_GMP
-    build-depends: integer-gmp >=0.2 && <1.2
-
   if flag(check-array-bound)
     cpp-options:   -DCHECK_ARRAY_BOUND
 
@@ -418,14 +401,6 @@
     , Z-Data
 
   c-sources:          test/cbits/ffi.c
-
-  if flag(integer-simple)
-    cpp-options:   -DINTEGER_SIMPLE
-    build-depends: integer-simple >=0.1 && <0.5
-
-  else
-    cpp-options:   -DINTEGER_GMP
-    build-depends: integer-gmp >=0.2 && <1.2
 
   if flag(check-array-bound)
     cpp-options:   -DCHECK_ARRAY_BOUND
diff --git a/Z/Data/ASCII.hs b/Z/Data/ASCII.hs
--- a/Z/Data/ASCII.hs
+++ b/Z/Data/ASCII.hs
@@ -20,13 +20,13 @@
 --
 w2c :: Word8 -> Char
 {-# INLINE w2c #-}
-w2c (W8# w#) = C# (chr# (word2Int# w#))
+w2c (W8# w#) = C# (chr# (word2Int# (word8ToWord# w#)))
 
 -- | Unsafe conversion between 'Char' and 'Word8'. This is a no-op and
 -- silently truncates to 8 bits Chars > @\\255@.
 c2w :: Char -> Word8
 {-# INLINE c2w #-}
-c2w (C# c#) = W8# (int2Word# (ord# c#))
+c2w (C# c#) = W8# (wordToWord8# (int2Word# (ord# c#)))
 
 -- | @\\NUL <= w && w <= \\DEL@
 isASCII :: Word8 -> Bool
diff --git a/Z/Data/Array/Base.hs b/Z/Data/Array/Base.hs
--- a/Z/Data/Array/Base.hs
+++ b/Z/Data/Array/Base.hs
@@ -29,7 +29,7 @@
 module Z.Data.Array.Base (
   -- * Arr typeclass
     Arr(..)
-  , emptyArr, singletonArr, doubletonArr
+  , singletonArr, doubletonArr
   , modifyIndexArr, insertIndexArr, deleteIndexArr, swapArr, swapMutableArr
   , doubleMutableArr, shuffleMutableArr
   , RealWorld
@@ -75,7 +75,7 @@
 import           Data.Primitive.SmallArray
 import           Data.Primitive.Types
 import           GHC.Exts
-import           System.Random.Stateful  ( UniformRange(uniformRM), StatefulGen )  
+import           System.Random.Stateful  ( UniformRange(uniformRM), StatefulGen )
 import           Z.Data.Array.Cast
 import           Z.Data.Array.UnliftedArray
 
@@ -105,6 +105,8 @@
     --
     type MArr arr = (mar :: Type -> Type -> Type) | mar -> arr
 
+    -- | The empty array reference.
+    emptyArr :: Arr arr a => arr a
 
     -- | Make a new array with a given size.
     --
@@ -262,6 +264,8 @@
 
 instance Arr Array a where
     type MArr Array = MutableArray
+    emptyArr = emptyArray
+    {-# INLINE emptyArr #-}
     newArr n = newArray n uninitialized
     {-# INLINE newArr #-}
     newArrWith = newArray
@@ -347,6 +351,8 @@
 
 instance Arr SmallArray a where
     type MArr SmallArray = SmallMutableArray
+    emptyArr = emptySmallArray
+    {-# INLINE emptyArr #-}
     newArr n = newSmallArray n uninitialized
     {-# INLINE newArr #-}
     newArrWith = newSmallArray
@@ -433,6 +439,8 @@
 
 instance Prim a => Arr PrimArray a where
     type MArr PrimArray = MutablePrimArray
+    emptyArr = emptyPrimArray
+    {-# INLINE emptyArr #-}
     newArr = newPrimArray
     {-# INLINE newArr #-}
     newArrWith n x = do
@@ -454,10 +462,7 @@
     {-# INLINE indexArrM #-}
     freezeArr = freezePrimArray
     {-# INLINE freezeArr #-}
-    thawArr arr s l = do
-        marr' <- newPrimArray l
-        copyPrimArray marr' 0 arr s l
-        return marr'
+    thawArr = thawPrimArray
     {-# INLINE thawArr #-}
     unsafeFreezeArr = unsafeFreezePrimArray
     {-# INLINE unsafeFreezeArr #-}
@@ -497,6 +502,8 @@
 
 instance PrimUnlifted a => Arr UnliftedArray a where
     type MArr UnliftedArray = MutableUnliftedArray
+    emptyArr = emptyUnliftedArray
+    {-# INLINE emptyArr #-}
     newArr = unsafeNewUnliftedArray
     {-# INLINE newArr #-}
     newArrWith = newUnliftedArray
@@ -625,12 +632,6 @@
 
 --------------------------------------------------------------------------------
 
-emptyArr :: Arr arr a => arr a
-{-# NOINLINE emptyArr #-}
-emptyArr = runST $ do
-    marr <- newArrWith 0 uninitialized
-    unsafeFreezeArr marr
-
 singletonArr :: Arr arr a => a -> arr a
 {-# INLINE singletonArr #-}
 singletonArr x = runST $ do
@@ -693,8 +694,8 @@
 -- | Swap two elements under given index and return a new array.
 swapArr :: Arr arr a
              => arr a
-             -> Int 
              -> Int
+             -> Int
              -> arr a
 {-# INLINE swapArr #-}
 swapArr arr i j = runST $ do
@@ -705,15 +706,15 @@
 -- | Swap two elements under given index, no atomically guarantee is given.
 swapMutableArr :: (PrimMonad m, PrimState m ~ s, Arr arr a)
              => MArr arr s a
-             -> Int 
              -> Int
+             -> Int
              -> m ()
 {-# INLINE swapMutableArr #-}
 swapMutableArr marr i j = do
     x <- readArr marr i
     y <- readArr marr j
-    writeArr marr i y 
-    writeArr marr j x 
+    writeArr marr i y
+    writeArr marr j x
 
 -- | Resize mutable array to @max (given_size) (2 * original_size)@ if orignal array is smaller than @give_size@.
 doubleMutableArr :: (Arr arr a, PrimMonad m, PrimState m ~ s) => MArr arr s a -> Int -> m (MArr arr s a)
@@ -727,16 +728,16 @@
 
 -- | Shuffle array's elements in slice range.
 --
--- This function use <https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle Fisher-Yates> algorithm. 
-shuffleMutableArr :: (StatefulGen g m, PrimMonad m, PrimState m ~ s, Arr arr a) => g -> MArr arr s a 
+-- This function use <https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle Fisher-Yates> algorithm.
+shuffleMutableArr :: (StatefulGen g m, PrimMonad m, PrimState m ~ s, Arr arr a) => g -> MArr arr s a
             -> Int  -- ^ offset
             -> Int  -- ^ length
             -> m ()
 {-# INLINE shuffleMutableArr #-}
 shuffleMutableArr g marr off n = go (off+n-1)
-  where 
+  where
     go i | i < off+1 = return ()
          | otherwise = do
             j <- uniformRM (off, i) g
-            swapMutableArr marr i j 
-            go (i - 1) 
+            swapMutableArr marr i j
+            go (i - 1)
diff --git a/Z/Data/Array/Cast.hs b/Z/Data/Array/Cast.hs
--- a/Z/Data/Array/Cast.hs
+++ b/Z/Data/Array/Cast.hs
@@ -37,13 +37,13 @@
 
 instance Cast Int8  Word8 where
     {-# INLINE cast #-}
-    cast (I8# i) = W8# (narrow8Word# (int2Word# i))
+    cast (I8# i) = W8# (int8ToWord8# i)
 instance Cast Int16 Word16 where
     {-# INLINE cast #-}
-    cast (I16# i) = W16# (narrow16Word# (int2Word# i))
+    cast (I16# i) = W16# (int16ToWord16# i)
 instance Cast Int32 Word32 where
     {-# INLINE cast #-}
-    cast (I32# i) = W32# (narrow32Word# (int2Word# i))
+    cast (I32# i) = W32# (int32ToWord32# i)
 instance Cast Int64 Word64 where
     {-# INLINE cast #-}
 #if WORD_SIZE_IN_BITS < 64
@@ -57,13 +57,13 @@
 
 instance Cast Word8  Int8 where
     {-# INLINE cast #-}
-    cast (W8# i) = I8# (narrow8Int# (word2Int# i))
+    cast (W8# i) = I8# (word8ToInt8# i)
 instance Cast Word16 Int16 where
     {-# INLINE cast #-}
-    cast (W16# i) = I16# (narrow16Int# (word2Int# i))
+    cast (W16# i) = I16# (word16ToInt16# i)
 instance Cast Word32 Int32 where
     {-# INLINE cast #-}
-    cast (W32# i) = I32# (narrow32Int# (word2Int# i))
+    cast (W32# i) = I32# (word32ToInt32# i)
 instance Cast Word64 Int64 where
     {-# INLINE cast #-}
 #if WORD_SIZE_IN_BITS < 64
diff --git a/Z/Data/Array/Unaligned.hs b/Z/Data/Array/Unaligned.hs
--- a/Z/Data/Array/Unaligned.hs
+++ b/Z/Data/Array/Unaligned.hs
@@ -27,10 +27,6 @@
 
 #include "MachDeps.h"
 
--- toggle these defs to test different implements
-#define USE_BSWAP
--- #define USE_SHIFT
-
 --------------------------------------------------------------------------------
 
 newtype UnalignedSize a = UnalignedSize { getUnalignedSize :: Int } deriving (Show, Eq, Ord)
@@ -208,24 +204,32 @@
     {-# INLINE indexWord8ArrayAs# #-}
     indexWord8ArrayAs# ba# i# = W16# (indexWord8ArrayAsWord16# ba# i#)
 
+word16ToWord8# :: Word16# -> Word8#
+{-# INLINE word16ToWord8# #-}
+word16ToWord8# w# = wordToWord8# (word16ToWord# w#)
+
+word8ToWord16# :: Word8# -> Word16#
+{-# INLINE word8ToWord16# #-}
+word8ToWord16# w# = wordToWord16# (word8ToWord# w#)
+
 instance Unaligned (LE Word16) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 2
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (LE (W16# x#)) s0# =
-        let s1# = writeWord8Array# mba# i# x# s0#
-        in        writeWord8Array# mba# (i# +# 1#) (uncheckedShiftRL# x# 8#) s1#
+    writeWord8ArrayAs# mba# i# (LE (W16# x#)) s0 =
+        let s1 = writeWord8Array# mba# i# (word16ToWord8# x#) s0
+        in       writeWord8Array# mba# (i# +# 1#) (word16ToWord8# (uncheckedShiftRLWord16# x# 8#)) s1
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
         let !(# s1, w1# #) = readWord8Array# mba# i# s0
             !(# s2, w2# #) = readWord8Array# mba# (i# +# 1#) s1
-        in (# s2, LE (W16# (uncheckedShiftL# w2# 8# `or#` w1#)) #)
+        in (# s2, LE (W16# (uncheckedShiftRLWord16# (word8ToWord16# w2#) 8# `orWord16#` (word8ToWord16# w1#))) #)
     {-# INLINE indexWord8ArrayAs# #-}
     indexWord8ArrayAs# ba# i# =
         let w1# = indexWord8Array# ba# i#
             w2# = indexWord8Array# ba# (i# +# 1#)
-        in LE (W16# (uncheckedShiftL# w2# 8# `or#` w1#))
+        in LE (W16# (uncheckedShiftRLWord16# (word8ToWord16# w2#) 8# `orWord16#` (word8ToWord16# w1#)))
 #else
     USE_HOST_IMPL(LE)
 #endif
@@ -233,36 +237,23 @@
 instance Unaligned (BE Word16) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 2
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     USE_HOST_IMPL(BE)
 #else
--- on X86 we use bswap
--- TODO: find out if arch64 support this
-#if (defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH)) && defined(USE_BSWAP)
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (W16# x#)) = writeWord8ArrayAsWord16# mba# i# (byteSwap16# x#)
-    {-# INLINE readWord8ArrayAs# #-}
-    readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, x# #) = readWord8ArrayAsWord16# mba# i# s0
-        in (# s1, BE (W16# (byteSwap16# x#)) #)
-    {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# = BE (W16# (byteSwap16# (indexWord8ArrayAsWord16# ba# i#)))
-#else
-    {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (W16# x#)) s0# =
-        let s1# = writeWord8Array# mba# i# (uncheckedShiftRL# x# 8#) s0#
-        in        writeWord8Array# mba# (i# +# 1#) x# s1#
+    writeWord8ArrayAs# mba# i# (BE (W16# x#)) s0 =
+        let s1 = writeWord8Array# mba# i# (word16ToWord8# (uncheckedShiftRLWord16# x# 8#)) s0
+        in       writeWord8Array# mba# (i# +# 1#) (word16ToWord8# x#) s1
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, w2# #) = readWord8Array# mba# i# s0
-            !(# s2, w1# #) = readWord8Array# mba# (i# +# 1#) s1
-        in (# s2, BE (W16# (uncheckedShiftL# w2# 8# `or#`  w1#)) #)
+        let !(# s1, w1# #) = readWord8Array# mba# i# s0
+            !(# s2, w2# #) = readWord8Array# mba# (i# +# 1#) s1
+        in (# s2, BE (W16# (uncheckedShiftLWord16# (word8ToWord16# w1#) 8# `orWord16#` (word8ToWord16# w2#))) #)
     {-# INLINE indexWord8ArrayAs# #-}
     indexWord8ArrayAs# ba# i# =
-        let w2# = indexWord8Array# ba# i#
-            w1# = indexWord8Array# ba# (i# +# 1#)
-        in BE (W16# (uncheckedShiftL# w2# 8# `or#`  w1#))
-#endif
+        let w1# = indexWord8Array# ba# i#
+            w2# = indexWord8Array# ba# (i# +# 1#)
+        in BE (W16# (uncheckedShiftLWord16# (word8ToWord16# w1#) 8# `orWord16#` (word8ToWord16# w2#)))
 #endif
 
 --------------------------------------------------------------------------------
@@ -271,7 +262,7 @@
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 4
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (W32# x#) =  writeWord8ArrayAsWord32# mba# i# x#
+    writeWord8ArrayAs# mba# i# (W32# x#) s0 = writeWord8ArrayAsWord32# mba# i# x# s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
         let !(# s1, x# #) = readWord8ArrayAsWord32# mba# i# s0 in (# s1, W32# x# #)
@@ -282,31 +273,15 @@
 instance Unaligned (LE Word32) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 4
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (LE (W32# x#)) s0# =
-        let s1# = writeWord8Array# mba# i# x# s0#
-            s2# = writeWord8Array# mba# (i# +# 1#) (uncheckedShiftRL# x# 8#) s1#
-            s3# = writeWord8Array# mba# (i# +# 2#) (uncheckedShiftRL# x# 16#) s2#
-        in        writeWord8Array# mba# (i# +# 3#) (uncheckedShiftRL# x# 24#) s3#
+    writeWord8ArrayAs# mba# i# (LE w) s0 = writeWord8ArrayAs# mba# i# (byteSwap32 w) s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, w1# #) = readWord8Array# mba# i# s0
-            !(# s2, w2# #) = readWord8Array# mba# (i# +# 1#) s1
-            !(# s3, w3# #) = readWord8Array# mba# (i# +# 2#) s2
-            !(# s4, w4# #) = readWord8Array# mba# (i# +# 3#) s3
-        in (# s4, LE (W32# ((uncheckedShiftL# w4# 24#) `or#`
-                    (uncheckedShiftL# w3# 16#) `or#`
-                        (uncheckedShiftL# w2# 8#) `or#` w1#)) #)
+        let !(# s1, x# #) = readWord8ArrayAsWord32# mba# i# s0
+        in (# s1, LE (byteSwap32 (W32# x#)) #)
     {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# =
-        let w1# = indexWord8Array# ba# i#
-            w2# = indexWord8Array# ba# (i# +# 1#)
-            w3# = indexWord8Array# ba# (i# +# 2#)
-            w4# = indexWord8Array# ba# (i# +# 3#)
-        in LE (W32# ((uncheckedShiftL# w4# 24#) `or#`
-                    (uncheckedShiftL# w3# 16#) `or#`
-                        (uncheckedShiftL# w2# 8#) `or#` w1#))
+    indexWord8ArrayAs# ba# i# = LE (byteSwap32 (W32# (indexWord8ArrayAsWord32# ba# i#)))
 #else
     USE_HOST_IMPL(LE)
 #endif
@@ -317,43 +292,14 @@
 #if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
     USE_HOST_IMPL(BE)
 #else
--- on X86 we use bswap
--- TODO: find out if arch64 support this
-#if (defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH)) && defined(USE_BSWAP)
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (W32# x#)) = writeWord8ArrayAsWord32# mba# i# (byteSwap32# x#)
+    writeWord8ArrayAs# mba# i# (BE x) s0 = writeWord8ArrayAs# mba# i# (byteSwap32 x) s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
         let !(# s1, x# #) = readWord8ArrayAsWord32# mba# i# s0
-        in (# s1, BE (W32# (byteSwap32# x#)) #)
-    {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# = BE (W32# (byteSwap32# (indexWord8ArrayAsWord32# ba# i#)))
-#else
-    {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (W32# x#)) s0# =
-        let s1# = writeWord8Array# mba# i# (uncheckedShiftRL# x# 24#) s0#
-            s2# = writeWord8Array# mba# (i# +# 1#) (uncheckedShiftRL# x# 16#) s1#
-            s3# = writeWord8Array# mba# (i# +# 2#) (uncheckedShiftRL# x# 8#) s2#
-        in        writeWord8Array# mba# (i# +# 3#) x# s3#
-    {-# INLINE readWord8ArrayAs# #-}
-    readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, w4# #) = readWord8Array# mba# i# s0
-            !(# s2, w3# #) = readWord8Array# mba# (i# +# 1#) s1
-            !(# s3, w2# #) = readWord8Array# mba# (i# +# 2#) s2
-            !(# s4, w1# #) = readWord8Array# mba# (i# +# 3#) s3
-        in (# s4, BE (W32# ((uncheckedShiftL# w4# 24#) `or#`
-                    (uncheckedShiftL# w3# 16#) `or#`
-                        (uncheckedShiftL# w2# 8#) `or#` w1#)) #)
+        in (# s1, BE (byteSwap32 (W32# x#)) #)
     {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# =
-        let w4# = indexWord8Array# ba# i#
-            w3# = indexWord8Array# ba# (i# +# 1#)
-            w2# = indexWord8Array# ba# (i# +# 2#)
-            w1# = indexWord8Array# ba# (i# +# 3#)
-        in BE (W32# ((uncheckedShiftL# w4# 24#) `or#`
-                    (uncheckedShiftL# w3# 16#) `or#`
-                        (uncheckedShiftL# w2# 8#) `or#` w1#))
-#endif
+    indexWord8ArrayAs# ba# i# = BE (byteSwap32 (W32# (indexWord8ArrayAsWord32# ba# i#)))
 #endif
 
 --------------------------------------------------------------------------------
@@ -362,7 +308,7 @@
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 8
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (W64# x#) =  writeWord8ArrayAsWord64# mba# i# x#
+    writeWord8ArrayAs# mba# i# (W64# x#) s0 = writeWord8ArrayAsWord64# mba# i# x# s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
         let !(# s1, x# #) = readWord8ArrayAsWord64# mba# i# s0 in (# s1, W64# x# #)
@@ -373,51 +319,15 @@
 instance Unaligned (LE Word64) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 8
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (LE (W64# x#)) s0# =
-        let s1# = writeWord8Array# mba# i# x# s0#
-            s2# = writeWord8Array# mba# (i# +# 1#) (uncheckedShiftRL# x# 8#) s1#
-            s3# = writeWord8Array# mba# (i# +# 2#) (uncheckedShiftRL# x# 16#) s2#
-            s4# = writeWord8Array# mba# (i# +# 3#) (uncheckedShiftRL# x# 24#) s3#
-            s5# = writeWord8Array# mba# (i# +# 4#) (uncheckedShiftRL# x# 32#) s4#
-            s6# = writeWord8Array# mba# (i# +# 5#) (uncheckedShiftRL# x# 40#) s5#
-            s7# = writeWord8Array# mba# (i# +# 6#) (uncheckedShiftRL# x# 48#) s6#
-        in        writeWord8Array# mba# (i# +# 7#) (uncheckedShiftRL# x# 56#) s7#
+    writeWord8ArrayAs# mba# i# (LE w) s0 = writeWord8ArrayAs# mba# i# (byteSwap64 w) s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, w1# #) = readWord8Array# mba# i# s0
-            !(# s2, w2# #) = readWord8Array# mba# (i# +# 1#) s1
-            !(# s3, w3# #) = readWord8Array# mba# (i# +# 2#) s2
-            !(# s4, w4# #) = readWord8Array# mba# (i# +# 3#) s3
-            !(# s5, w5# #) = readWord8Array# mba# (i# +# 4#) s4
-            !(# s6, w6# #) = readWord8Array# mba# (i# +# 5#) s5
-            !(# s7, w7# #) = readWord8Array# mba# (i# +# 6#) s6
-            !(# s8, w8# #) = readWord8Array# mba# (i# +# 7#) s7
-        in (# s8, LE (W64# ((uncheckedShiftL# w8# 56#) `or#`
-                    (uncheckedShiftL# w7# 48#) `or#`
-                        (uncheckedShiftL# w6# 40#) `or#`
-                            (uncheckedShiftL# w5# 32#) `or#`
-                                (uncheckedShiftL# w4# 24#) `or#`
-                                    (uncheckedShiftL# w3# 16#) `or#`
-                                        (uncheckedShiftL# w2# 8#) `or#` w1#)) #)
+        let !(# s1, x# #) = readWord8ArrayAsWord64# mba# i# s0
+        in (# s1, LE (byteSwap64 (W64# x#)) #)
     {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# =
-        let w1# = indexWord8Array# ba# i#
-            w2# = indexWord8Array# ba# (i# +# 1#)
-            w3# = indexWord8Array# ba# (i# +# 2#)
-            w4# = indexWord8Array# ba# (i# +# 3#)
-            w5# = indexWord8Array# ba# (i# +# 4#)
-            w6# = indexWord8Array# ba# (i# +# 5#)
-            w7# = indexWord8Array# ba# (i# +# 6#)
-            w8# = indexWord8Array# ba# (i# +# 7#)
-        in LE (W64# ((uncheckedShiftL# w8# 56#) `or#`
-                    (uncheckedShiftL# w7# 48#) `or#`
-                        (uncheckedShiftL# w6# 40#) `or#`
-                            (uncheckedShiftL# w5# 32#) `or#`
-                                (uncheckedShiftL# w4# 24#) `or#`
-                                    (uncheckedShiftL# w3# 16#) `or#`
-                                        (uncheckedShiftL# w2# 8#) `or#` w1#))
+    indexWord8ArrayAs# ba# i# = LE (byteSwap64 (W64# (indexWord8ArrayAsWord64# ba# i#)))
 #else
     USE_HOST_IMPL(LE)
 #endif
@@ -428,63 +338,14 @@
 #if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
     USE_HOST_IMPL(BE)
 #else
--- on X86 we use bswap
--- TODO: find out if arch64 support this
-#if (defined(i386_HOST_ARCH) || defined(x86_64_HOST_ARCH)) && defined(USE_BSWAP)
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (W64# x#)) = writeWord8ArrayAsWord64# mba# i# (byteSwap64# x#)
+    writeWord8ArrayAs# mba# i# (BE x) s0 = writeWord8ArrayAs# mba# i# (byteSwap64 x) s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
         let !(# s1, x# #) = readWord8ArrayAsWord64# mba# i# s0
-        in (# s1, BE (W64# (byteSwap64# x#)) #)
-    {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# = BE (W64# (byteSwap64# (indexWord8ArrayAsWord64# ba# i#)))
-#else
-    {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (W64# x#)) s0# =
-        let s1# = writeWord8Array# mba# i# (uncheckedShiftRL# x# 56#) s0#
-            s2# = writeWord8Array# mba# (i# +# 1#) (uncheckedShiftRL# x# 48#) s1#
-            s3# = writeWord8Array# mba# (i# +# 2#) (uncheckedShiftRL# x# 40#) s2#
-            s4# = writeWord8Array# mba# (i# +# 3#) (uncheckedShiftRL# x# 32#) s3#
-            s5# = writeWord8Array# mba# (i# +# 4#) (uncheckedShiftRL# x# 24#) s4#
-            s6# = writeWord8Array# mba# (i# +# 5#) (uncheckedShiftRL# x# 16#) s5#
-            s7# = writeWord8Array# mba# (i# +# 6#) (uncheckedShiftRL# x# 8#) s6#
-        in        writeWord8Array# mba# (i# +# 7#) x# s7#
-    {-# INLINE readWord8ArrayAs# #-}
-    readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, w8# #) = readWord8Array# mba# i# s0
-            !(# s2, w7# #) = readWord8Array# mba# (i# +# 1#) s1
-            !(# s3, w6# #) = readWord8Array# mba# (i# +# 2#) s2
-            !(# s4, w5# #) = readWord8Array# mba# (i# +# 3#) s3
-            !(# s5, w4# #) = readWord8Array# mba# (i# +# 4#) s4
-            !(# s6, w3# #) = readWord8Array# mba# (i# +# 5#) s5
-            !(# s7, w2# #) = readWord8Array# mba# (i# +# 6#) s6
-            !(# s8, w1# #) = readWord8Array# mba# (i# +# 7#) s7
-        in (# s8, BE (W64# ((uncheckedShiftL# w8# 56#) `or#`
-                    (uncheckedShiftL# w7# 48#) `or#`
-                        (uncheckedShiftL# w6# 40#) `or#`
-                            (uncheckedShiftL# w5# 32#) `or#`
-                                (uncheckedShiftL# w4# 24#) `or#`
-                                    (uncheckedShiftL# w3# 16#) `or#`
-                                        (uncheckedShiftL# w2# 8#) `or#` w1#)) #)
+        in (# s1, BE (byteSwap64 (W64# x#)) #)
     {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# =
-        let w8# = indexWord8Array# ba# i#
-            w7# = indexWord8Array# ba# (i# +# 1#)
-            w6# = indexWord8Array# ba# (i# +# 2#)
-            w5# = indexWord8Array# ba# (i# +# 3#)
-            w4# = indexWord8Array# ba# (i# +# 4#)
-            w3# = indexWord8Array# ba# (i# +# 5#)
-            w2# = indexWord8Array# ba# (i# +# 6#)
-            w1# = indexWord8Array# ba# (i# +# 7#)
-        in BE (W64# ((uncheckedShiftL# w8# 56#) `or#`
-                    (uncheckedShiftL# w7# 48#) `or#`
-                        (uncheckedShiftL# w6# 40#) `or#`
-                            (uncheckedShiftL# w5# 32#) `or#`
-                                (uncheckedShiftL# w4# 24#) `or#`
-                                    (uncheckedShiftL# w3# 16#) `or#`
-                                        (uncheckedShiftL# w2# 8#) `or#` w1#))
-#endif
+    indexWord8ArrayAs# ba# i# = BE (byteSwap64 (W64# (indexWord8ArrayAsWord64# ba# i#)))
 #endif
 
 --------------------------------------------------------------------------------
@@ -498,7 +359,7 @@
     unalignedSize = UnalignedSize 8
 #endif
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (W# x#) = writeWord8ArrayAsWord# mba# i# x#
+    writeWord8ArrayAs# mba# i# (W# x#) s0 = writeWord8ArrayAsWord# mba# i# x# s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
         let !(# s1, x# #) = readWord8ArrayAsWord# mba# i# s0 in (# s1, W# x# #)
@@ -509,47 +370,33 @@
 #if SIZEOF_HSWORD == 4
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 4
-    {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (LE (W# x#)) = writeWord8ArrayAs# mba# i# (LE (W32# x#))
-    {-# INLINE readWord8ArrayAs# #-}
-    readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, LE (W32# x#) #) = readWord8ArrayAs# mba# i# s0 in (# s1, LE (W# x#) #)
-    {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# = case (indexWord8ArrayAs# ba# i#) of (LE (W32# x#)) -> LE (W# x#)
 #else
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 8
+#endif
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (LE (W# x#)) = writeWord8ArrayAs# mba# i# (LE (W64# x#))
+    writeWord8ArrayAs# mba# i# (LE (W# x#)) s0 = writeWord8ArrayAsWord# mba# i# (byteSwap# x#) s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, LE (W64# x#) #) = readWord8ArrayAs# mba# i# s0 in (# s1, LE (W# x#) #)
+        let !(# s1, x# #) = readWord8ArrayAsWord# mba# i# s0 in (# s1, LE (W# (byteSwap# x#)) #)
     {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# = case (indexWord8ArrayAs# ba# i#) of (LE (W64# x#)) -> LE (W# x#)
-#endif
+    indexWord8ArrayAs# ba# i# = LE (W# (byteSwap# (indexWord8ArrayAsWord# ba# i#)))
 
 instance Unaligned (BE Word) where
 #if SIZEOF_HSWORD == 4
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 4
-    {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (W# x#)) = writeWord8ArrayAs# mba# i# (BE (W32# x#))
-    {-# INLINE readWord8ArrayAs# #-}
-    readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, BE (W32# x#) #) = readWord8ArrayAs# mba# i# s0 in (# s1, BE (W# x#) #)
-    {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# = case (indexWord8ArrayAs# ba# i#) of (BE (W32# x#)) -> BE (W# x#)
 #else
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 8
+#endif
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (W# x#)) = writeWord8ArrayAs# mba# i# (BE (W64# x#))
+    writeWord8ArrayAs# mba# i# (BE (W# x#)) s0 = writeWord8ArrayAsWord# mba# i# (byteSwap# x#) s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, BE (W64# x#) #) = readWord8ArrayAs# mba# i# s0 in (# s1, BE (W# x#) #)
+        let !(# s1, x# #) = readWord8ArrayAsWord# mba# i# s0 in (# s1, BE (W# (byteSwap# x#)) #)
     {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# = case (indexWord8ArrayAs# ba# i#) of (BE (W64# x#)) -> BE (W# x#)
-#endif
+    indexWord8ArrayAs# ba# i# = BE (W# (byteSwap# (indexWord8ArrayAsWord# ba# i#)))
 
 --------------------------------------------------------------------------------
 
@@ -564,21 +411,28 @@
     {-# INLINE indexWord8ArrayAs# #-}
     indexWord8ArrayAs# ba# i# = I16# (indexWord8ArrayAsInt16# ba# i#)
 
+int16ToWord8# :: Int16# -> Word8#
+{-# INLINE int16ToWord8# #-}
+int16ToWord8# w# = wordToWord8# (word16ToWord# (int16ToWord16# w#))
+
 instance Unaligned (LE Int16) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 2
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (LE (I16# x#)) =
-        writeWord8ArrayAs# mba# i# (LE (W16# (int2Word# x#)))
+    writeWord8ArrayAs# mba# i# (LE (I16# x#)) s0 =
+        let s1 = writeWord8Array# mba# i# (int16ToWord8# x#) s0
+        in       writeWord8Array# mba# (i# +# 1#) (int16ToWord8# (uncheckedShiftRLInt16# x# 8#)) s1
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, LE (W16# x#) #) = readWord8ArrayAs# mba# i# s0
-        in (# s1, LE (I16# (narrow16Int# (word2Int# x#))) #)
+        let !(# s1, w1# #) = readWord8Array# mba# i# s0
+            !(# s2, w2# #) = readWord8Array# mba# (i# +# 1#) s1
+        in (# s2, LE (I16# (word16ToInt16# (uncheckedShiftRLWord16# (word8ToWord16# w2#) 8# `orWord16#` (word8ToWord16# w1#)))) #)
     {-# INLINE indexWord8ArrayAs# #-}
     indexWord8ArrayAs# ba# i# =
-        let LE (W16# x#) = indexWord8ArrayAs# ba# i#
-        in LE (I16# (narrow16Int# (word2Int# x#)))
+        let w1# = indexWord8Array# ba# i#
+            w2# = indexWord8Array# ba# (i# +# 1#)
+        in LE (I16# (word16ToInt16# (uncheckedShiftRLWord16# (word8ToWord16# w2#) 8# `orWord16#` (word8ToWord16# w1#))))
 #else
     USE_HOST_IMPL(LE)
 #endif
@@ -586,20 +440,23 @@
 instance Unaligned (BE Int16) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 2
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     USE_HOST_IMPL(BE)
 #else
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (I16# x#)) =
-        writeWord8ArrayAs# mba# i# (BE (W16# (int2Word# x#)))
+    writeWord8ArrayAs# mba# i# (BE (I16# x#)) s0 =
+        let s1 = writeWord8Array# mba# i# (int16ToWord8# (uncheckedShiftRLInt16# x# 8#)) s0
+        in       writeWord8Array# mba# (i# +# 1#) (int16ToWord8# x#) s1
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, BE (W16# x#) #) = readWord8ArrayAs# mba# i# s0
-        in (# s1, BE (I16# (narrow16Int# (word2Int# x#))) #)
+        let !(# s1, w1# #) = readWord8Array# mba# i# s0
+            !(# s2, w2# #) = readWord8Array# mba# (i# +# 1#) s1
+        in (# s2, BE (I16# (word16ToInt16# (uncheckedShiftLWord16# (word8ToWord16# w1#) 8# `orWord16#` (word8ToWord16# w2#)))) #)
     {-# INLINE indexWord8ArrayAs# #-}
     indexWord8ArrayAs# ba# i# =
-        let !(BE (W16# x#)) = indexWord8ArrayAs# ba# i#
-        in BE (I16# (narrow16Int# (word2Int# x#)))
+        let w1# = indexWord8Array# ba# i#
+            w2# = indexWord8Array# ba# (i# +# 1#)
+        in BE (I16# (word16ToInt16# (uncheckedShiftLWord16# (word8ToWord16# w1#) 8# `orWord16#` (word8ToWord16# w2#))))
 #endif
 
 --------------------------------------------------------------------------------
@@ -608,28 +465,29 @@
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 4
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (I32# x#) = writeWord8ArrayAsInt32# mba# i# x#
+    writeWord8ArrayAs# mba# i# (I32# x#) s0 = writeWord8ArrayAsInt32# mba# i# x# s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
         let !(# s1, x# #) = readWord8ArrayAsInt32# mba# i# s0 in (# s1, I32# x# #)
     {-# INLINE indexWord8ArrayAs# #-}
     indexWord8ArrayAs# ba# i# = I32# (indexWord8ArrayAsInt32# ba# i#)
 
+byteSwapInt32 :: Int32 -> Int32
+{-# INLINE byteSwapInt32 #-}
+byteSwapInt32 i = fromIntegral (byteSwap32 (fromIntegral i))
+
 instance Unaligned (LE Int32) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 4
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (LE (I32# x#)) =
-        writeWord8ArrayAs# mba# i# (LE (W32# (int2Word# x#)))
+    writeWord8ArrayAs# mba# i# (LE w) s0 = writeWord8ArrayAs# mba# i# (byteSwapInt32 w) s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, LE (W32# x#) #) = readWord8ArrayAs# mba# i# s0
-        in (# s1, LE (I32# (narrow32Int# (word2Int# x#))) #)
+        let !(# s1, x# #) = readWord8ArrayAsWord32# mba# i# s0
+        in (# s1, LE (byteSwapInt32 (I32# x#)) #)
     {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# =
-        let LE (W32# x#) = indexWord8ArrayAs# ba# i#
-        in LE (I32# (narrow32Int# (word2Int# x#)))
+    indexWord8ArrayAs# ba# i# = LE (byteSwapInt32 (I32# (indexWord8ArrayAsInt32# ba# i#)))
 #else
     USE_HOST_IMPL(LE)
 #endif
@@ -641,16 +499,13 @@
     USE_HOST_IMPL(BE)
 #else
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (I32# x#)) =
-        writeWord8ArrayAs# mba# i# (BE (W32# (int2Word# x#)))
+    writeWord8ArrayAs# mba# i# (BE x) s0 = writeWord8ArrayAs# mba# i# (byteSwapInt32 x) s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, BE (W32# x#) #) = readWord8ArrayAs# mba# i# s0
-        in (# s1, BE (I32# (narrow32Int# (word2Int# x#))) #)
+        let !(# s1, x# #) = readWord8ArrayAsInt32# mba# i# s0
+        in (# s1, BE (byteSwapInt32 (I32# x#)) #)
     {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# =
-        let !(BE (W32# x#)) = indexWord8ArrayAs# ba# i#
-        in BE (I32# (narrow32Int# (word2Int# x#)))
+    indexWord8ArrayAs# ba# i# = BE (byteSwapInt32 (I32# (indexWord8ArrayAsInt32# ba# i#)))
 #endif
 
 --------------------------------------------------------------------------------
@@ -659,28 +514,29 @@
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 8
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (I64# x#) = writeWord8ArrayAsInt64# mba# i# x#
+    writeWord8ArrayAs# mba# i# (I64# x#) s0 = writeWord8ArrayAsInt64# mba# i# x# s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
         let !(# s1, x# #) = readWord8ArrayAsInt64# mba# i# s0 in (# s1, I64# x# #)
     {-# INLINE indexWord8ArrayAs# #-}
     indexWord8ArrayAs# ba# i# = I64# (indexWord8ArrayAsInt64# ba# i#)
 
+byteSwapInt64 :: Int64 -> Int64
+{-# INLINE byteSwapInt64 #-}
+byteSwapInt64 i = fromIntegral (byteSwap64 (fromIntegral i))
+
 instance Unaligned (LE Int64) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 8
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (LE (I64# x#)) =
-        writeWord8ArrayAs# mba# i# (LE (W64# (int2Word# x#)))
+    writeWord8ArrayAs# mba# i# (LE w) s0 = writeWord8ArrayAs# mba# i# (byteSwapInt64 w) s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, LE (W64# x#) #) = readWord8ArrayAs# mba# i# s0
-        in (# s1, LE (I64# (word2Int# x#)) #)
+        let !(# s1, x# #) = readWord8ArrayAsInt64# mba# i# s0
+        in (# s1, LE (byteSwapInt64 (I64# x#)) #)
     {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# =
-        let LE (W64# x#) = indexWord8ArrayAs# ba# i#
-        in LE (I64# (word2Int# x#))
+    indexWord8ArrayAs# ba# i# = LE (byteSwapInt64 (I64# (indexWord8ArrayAsInt64# ba# i#)))
 #else
     USE_HOST_IMPL(LE)
 #endif
@@ -692,16 +548,13 @@
     USE_HOST_IMPL(BE)
 #else
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (I64# x#)) =
-        writeWord8ArrayAs# mba# i# (BE (W64# (int2Word# x#)))
+    writeWord8ArrayAs# mba# i# (BE x) s0 = writeWord8ArrayAs# mba# i# (byteSwapInt64 x) s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, BE (W64# x#) #) = readWord8ArrayAs# mba# i# s0
-        in (# s1, BE (I64# (word2Int# x#)) #)
+        let !(# s1, x# #) = readWord8ArrayAsInt64# mba# i# s0
+        in (# s1, BE (byteSwapInt64 (I64# x#)) #)
     {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# =
-        let !(BE (W64# x#)) = indexWord8ArrayAs# ba# i#
-        in BE (I64# (word2Int# x#))
+    indexWord8ArrayAs# ba# i# = BE (byteSwapInt64 (I64# (indexWord8ArrayAsInt64# ba# i#)))
 #endif
 
 --------------------------------------------------------------------------------
@@ -715,58 +568,48 @@
     unalignedSize = UnalignedSize 8
 #endif
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (I# x#) = writeWord8ArrayAsInt# mba# i# x#
+    writeWord8ArrayAs# mba# i# (I# x#) s0 = writeWord8ArrayAsInt# mba# i# x# s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
         let !(# s1, x# #) = readWord8ArrayAsInt# mba# i# s0 in (# s1, I# x# #)
     {-# INLINE indexWord8ArrayAs# #-}
     indexWord8ArrayAs# ba# i# = I# (indexWord8ArrayAsInt# ba# i#)
 
+byteSwapInt :: Int -> Int
+{-# INLINE byteSwapInt #-}
+byteSwapInt (I# i#) = I# (word2Int# (byteSwap# (int2Word# i#)))
+
 instance Unaligned (LE Int) where
 #if SIZEOF_HSWORD == 4
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 4
-    {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (LE (I# x#)) = writeWord8ArrayAs# mba# i# (LE (I32# x#))
-    {-# INLINE readWord8ArrayAs# #-}
-    readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, LE (I32# x#) #) = readWord8ArrayAs# mba# i# s0 in (# s1, LE (I# x#) #)
-    {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# = case (indexWord8ArrayAs# ba# i#) of (LE (I32# x#)) -> LE (I# x#)
 #else
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 8
+#endif
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (LE (I# x#)) = writeWord8ArrayAs# mba# i# (LE (I64# x#))
+    writeWord8ArrayAs# mba# i# (LE x) s0 = writeWord8ArrayAs# mba# i# (byteSwapInt x) s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, LE (I64# x#) #) = readWord8ArrayAs# mba# i# s0 in (# s1, LE (I# x#) #)
+        let !(# s1, x #) = readWord8ArrayAs# mba# i# s0 in (# s1, LE (byteSwapInt x) #)
     {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# = case (indexWord8ArrayAs# ba# i#) of (LE (I64# x#)) -> LE (I# x#)
-#endif
+    indexWord8ArrayAs# ba# i# = LE (byteSwapInt (indexWord8ArrayAs# ba# i#))
 
 instance Unaligned (BE Int) where
 #if SIZEOF_HSWORD == 4
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 4
-    {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (I# x#)) = writeWord8ArrayAs# mba# i# (BE (I32# x#))
-    {-# INLINE readWord8ArrayAs# #-}
-    readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, BE (I32# x#) #) = readWord8ArrayAs# mba# i# s0 in (# s1, BE (I# x#) #)
-    {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# = case (indexWord8ArrayAs# ba# i#) of (BE (I32# x#)) -> BE (I# x#)
 #else
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 8
+#endif
     {-# INLINE writeWord8ArrayAs# #-}
-    writeWord8ArrayAs# mba# i# (BE (I# x#)) = writeWord8ArrayAs# mba# i# (BE (I64# x#))
+    writeWord8ArrayAs# mba# i# (BE x) s0 = writeWord8ArrayAs# mba# i# (byteSwapInt x) s0
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
-        let !(# s1, BE (I64# x#) #) = readWord8ArrayAs# mba# i# s0 in (# s1, BE (I# x#) #)
+        let !(# s1, x #) = readWord8ArrayAs# mba# i# s0 in (# s1, BE (byteSwapInt x) #)
     {-# INLINE indexWord8ArrayAs# #-}
-    indexWord8ArrayAs# ba# i# = case (indexWord8ArrayAs# ba# i#) of (BE (I64# x#)) -> BE (I# x#)
-#endif
+    indexWord8ArrayAs# ba# i# = BE (byteSwapInt (indexWord8ArrayAs# ba# i#))
 
 --------------------------------------------------------------------------------
 
@@ -795,7 +638,7 @@
 instance Unaligned (LE Float) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 4
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     {-# INLINE writeWord8ArrayAs# #-}
     writeWord8ArrayAs# mba# i# (LE (F# x#)) =
         writeWord8ArrayAs# mba# i# (LE (W32# (stgFloatToWord32 x#)))
@@ -814,7 +657,7 @@
 instance Unaligned (BE Float) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 4
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     USE_HOST_IMPL(BE)
 #else
     {-# INLINE writeWord8ArrayAs# #-}
@@ -846,7 +689,7 @@
 instance Unaligned (LE Double) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 8
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     {-# INLINE writeWord8ArrayAs# #-}
     writeWord8ArrayAs# mba# i# (LE (D# x#)) =
         writeWord8ArrayAs# mba# i# (LE (W64# (stgDoubleToWord64 x#)))
@@ -865,7 +708,7 @@
 instance Unaligned (BE Double) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 8
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     USE_HOST_IMPL(BE)
 #else
     {-# INLINE writeWord8ArrayAs# #-}
@@ -898,7 +741,7 @@
 instance Unaligned (LE Char) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 4
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     {-# INLINE writeWord8ArrayAs# #-}
     writeWord8ArrayAs# mba# i# (LE (C# x#)) =
         writeWord8ArrayAs# mba# i# (LE (I32# (ord# x#)))
@@ -917,20 +760,20 @@
 instance Unaligned (BE Char) where
     {-# INLINE unalignedSize #-}
     unalignedSize = UnalignedSize 4
-#if defined(WORDS_BIGENDIAN) || defined(USE_SHIFT)
+#if defined(WORDS_BIGENDIAN)
     USE_HOST_IMPL(BE)
 #else
     {-# INLINE writeWord8ArrayAs# #-}
     writeWord8ArrayAs# mba# i# (BE (C# x#)) =
-        writeWord8ArrayAs# mba# i# (BE (I32# (ord# x#)))
+        writeWord8ArrayAs# mba# i# (BE (I32# (intToInt32# (ord# x#))))
     {-# INLINE readWord8ArrayAs# #-}
     readWord8ArrayAs# mba# i# s0 =
         let !(# s1, BE (I32# x#) #) = readWord8ArrayAs# mba# i# s0
-        in (# s1, BE (C# (chr# x#)) #)
+        in (# s1, BE (C# (chr# (int32ToInt# x#))) #)
     {-# INLINE indexWord8ArrayAs# #-}
     indexWord8ArrayAs# ba# i# =
         let !(BE (I32# x#)) = indexWord8ArrayAs# ba# i#
-        in BE (C# (chr# x#))
+        in BE (C# (chr# (int32ToInt# x#)))
 #endif
 
 -- | Write a, b in order
diff --git a/Z/Data/Array/UnliftedArray.hs b/Z/Data/Array/UnliftedArray.hs
--- a/Z/Data/Array/UnliftedArray.hs
+++ b/Z/Data/Array/UnliftedArray.hs
@@ -37,6 +37,7 @@
 -}
 module Z.Data.Array.UnliftedArray where
 
+import Control.Exception              (ArrayException (..), throw)
 import Control.Monad.Primitive
 import Data.Primitive.Array
 import Data.Primitive.ByteArray
@@ -44,6 +45,7 @@
 import Data.Primitive.SmallArray
 import GHC.MVar (MVar(..))
 import GHC.IORef (IORef(..))
+import GHC.ST
 import GHC.STRef (STRef(..))
 import GHC.Conc (TVar(..))
 import GHC.Exts
@@ -219,8 +221,19 @@
     => Int -- ^ size
     -> m (MutableUnliftedArray (PrimState m) a)
 {-# INLINE unsafeNewUnliftedArray #-}
+unsafeNewUnliftedArray 0 = primitive $ \s ->
+    -- GHC 9.2 has a bug: call newArrayArray# with 0# length will hang
+    -- so we unsafeCoerce# empty Array# into ArrayArray# here
+    case newArray# 0# (throw (UndefinedElement "Data.Array.UnliftedArray.uninitialized")) s of
+        (# s', maa# #) -> (# s', MutableUnliftedArray (unsafeCoerce# maa#) #)
 unsafeNewUnliftedArray (I# i#) = primitive $ \s -> case newArrayArray# i# s of
     (# s', maa# #) -> (# s', MutableUnliftedArray maa# #)
+
+emptyUnliftedArray :: PrimUnlifted a => UnliftedArray a
+{-# NOINLINE emptyUnliftedArray #-}
+emptyUnliftedArray = runST (do
+    mua <- unsafeNewUnliftedArray 0
+    unsafeFreezeUnliftedArray mua)
 
 -- | Creates a new 'MutableUnliftedArray' with the specified value as initial
 -- contents. This is slower than 'unsafeNewUnliftedArray', but safer.
diff --git a/Z/Data/Builder/Base.hs b/Z/Data/Builder/Base.hs
--- a/Z/Data/Builder/Base.hs
+++ b/Z/Data/Builder/Base.hs
@@ -65,7 +65,6 @@
 import           Data.Primitive.Ptr                 (copyPtrToMutablePrimArray)
 import           Data.Word
 import           Data.Int
-import           GHC.CString                        (unpackCString#, unpackCStringUtf8#)
 import           GHC.Exts                           hiding (build)
 import           GHC.Stack
 import           Data.Primitive.PrimArray
@@ -139,7 +138,7 @@
     {-# INLINE (>>=) #-}
     (Builder b) >>= f = Builder (\ k -> b ( \ a -> runBuilder (f a) k))
     {-# INLINE (>>) #-}
-    (>>) = append
+    (>>) = (*>)
 
 instance Semigroup (Builder ()) where
     (<>) = append
@@ -148,7 +147,7 @@
 instance Monoid (Builder ()) where
     mempty = pure ()
     {-# INLINE mempty #-}
-    mappend = append
+    mappend = (<>)
     {-# INLINE mappend #-}
     mconcat = foldr append (pure ())
     {-# INLINE mconcat #-}
diff --git a/Z/Data/Builder/Numeric.hs b/Z/Data/Builder/Numeric.hs
--- a/Z/Data/Builder/Numeric.hs
+++ b/Z/Data/Builder/Numeric.hs
@@ -50,15 +50,12 @@
 import           Data.Word
 import           GHC.Exts
 import           GHC.Float
-import           GHC.Integer
+import           GHC.Num
 import           Z.Data.ASCII
 import           Z.Data.Builder.Base
 import           Z.Data.Builder.Numeric.DigitTable
 import           Z.Foreign
 import           System.IO.Unsafe
-#ifdef INTEGER_GMP
-import           GHC.Integer.GMP.Internals
-#endif
 import           Test.QuickCheck.Arbitrary           (Arbitrary(..), CoArbitrary(..))
 
 --------------------------------------------------------------------------------
@@ -368,9 +365,7 @@
 -- | Format a 'Integer' into decimal ASCII digits.
 integer :: Integer -> Builder ()
 {-# INLINE integer #-}
-#ifdef INTEGER_GMP
-integer (S# i#) = int (I# i#)
-#endif
+integer (IS i#) = int (I# i#)
 -- Divide and conquer implementation of string conversion
 integer n0
     | n0 < 0    = encodePrim MINUS >> integer' (-n0)
@@ -386,7 +381,7 @@
     -- that all fit into a machine word.
     jprinth :: [Integer] -> Builder ()
     jprinth (n:ns) =
-        case n `quotRemInteger` BASE of
+        case n `integerQuotRem#` BASE of
         (# q', r' #) ->
             let q = fromInteger q'
                 r = fromInteger r'
@@ -396,7 +391,7 @@
 
     jprintb :: [Integer] -> Builder ()
     jprintb []     = pure ()
-    jprintb (n:ns) = case n `quotRemInteger` BASE of
+    jprintb (n:ns) = case n `integerQuotRem#` BASE of
                         (# q', r' #) ->
                             let q = fromInteger q'
                                 r = fromInteger r'
@@ -422,7 +417,7 @@
 
     jsplith :: Integer -> [Integer] -> [Integer]
     jsplith p (n:ns) =
-        case n `quotRemInteger` p of
+        case n `integerQuotRem#` p of
         (# q, r #) ->
             if q > 0 then q : r : jsplitb p ns
                      else     r : jsplitb p ns
@@ -430,7 +425,7 @@
 
     jsplitb :: Integer -> [Integer] -> [Integer]
     jsplitb _ []     = []
-    jsplitb p (n:ns) = case n `quotRemInteger` p of
+    jsplitb p (n:ns) = case n `integerQuotRem#` p of
                        (# q, r #) ->
                            q : r : jsplitb p ns
 
@@ -630,9 +625,7 @@
     if c == 0
     then ([0], 0)
     else case c of
-#ifdef INTEGER_GMP
-        (S# i#) -> goI (W# (int2Word# i#)) 0 []
-#endif
+        (IS i#) -> goI (W# (int2Word# i#)) 0 []
         _ -> go c 0 []
   where
     sci' = Sci.normalize sci
@@ -641,13 +634,11 @@
 
     go :: Integer -> Int -> [Int] -> ([Int], Int)
     go 0 !n ds = let !ne = n + e in (ds, ne)
-    go i !n ds = case i `quotRemInteger` 10 of
+    go i !n ds = case i `integerQuotRem#` 10 of
                      (# q, r #) -> let !d = fromIntegral r in go q (n+1) (d:ds)
-#ifdef INTEGER_GMP
     goI :: Word -> Int -> [Int] -> ([Int], Int)
     goI 0 !n ds = let !ne = n + e in (ds, ne)
     goI i !n ds = case quotRem10 i of (q, r) -> let !d = fromIntegral r in goI q (n+1) (d:ds)
-#endif
 
 -- | A faster `quotRem` by 10.
 quotRem10 :: Word -> (Word, Word)
diff --git a/Z/Data/CBytes.hs b/Z/Data/CBytes.hs
--- a/Z/Data/CBytes.hs
+++ b/Z/Data/CBytes.hs
@@ -42,7 +42,6 @@
 import qualified Data.List                 as List
 import           Data.Word
 import           Foreign.C.String
-import           GHC.CString
 import           GHC.Exts
 import           GHC.Ptr
 import           GHC.Stack
@@ -174,7 +173,7 @@
     {-# INLINE mempty #-}
     mempty  = empty
     {-# INLINE mappend #-}
-    mappend = append
+    mappend = (<>)
     {-# INLINE mconcat #-}
     mconcat = concat
 
diff --git a/Z/Data/Generics/Utils.hs b/Z/Data/Generics/Utils.hs
--- a/Z/Data/Generics/Utils.hs
+++ b/Z/Data/Generics/Utils.hs
@@ -23,9 +23,10 @@
 import GHC.Generics
 import GHC.TypeNats
 import GHC.Exts (Proxy#, proxy#)
+import Data.Kind
 
 -- | type class for calculating product size.
-class KnownNat (PSize f) => ProductSize (f :: * -> *) where
+class KnownNat (PSize f) => ProductSize (f :: Type -> Type) where
     type PSize f :: Nat
 
 instance ProductSize (S1 s a) where
@@ -38,7 +39,7 @@
 productSize _ = fromIntegral (natVal' (proxy# :: Proxy# (PSize f)))
 
 
-class KnownNat (SSize f) => SumSize (f :: * -> *) where
+class KnownNat (SSize f) => SumSize (f :: Type -> Type) where
     type SSize f :: Nat
 
 instance SumSize (C1 c a) where
diff --git a/Z/Data/Parser/Base.hs b/Z/Data/Parser/Base.hs
--- a/Z/Data/Parser/Base.hs
+++ b/Z/Data/Parser/Base.hs
@@ -53,7 +53,7 @@
 import           Data.Int
 import           Data.Word
 import           Data.Bits                          ((.&.))
-import           GHC.Types
+import           GHC.IO
 import           GHC.Exts                           (State#, runRW#, unsafeCoerce#)
 import           Prelude                            hiding (take, takeWhile, decodeFloat)
 import           Z.Data.Array.Unaligned
diff --git a/Z/Data/Parser/Numeric.hs b/Z/Data/Parser/Numeric.hs
--- a/Z/Data/Parser/Numeric.hs
+++ b/Z/Data/Parser/Numeric.hs
@@ -41,10 +41,8 @@
 import           Data.Int
 import qualified Data.Scientific        as Sci
 import           Data.Word
-#ifdef INTEGER_GMP
-import           GHC.Integer.GMP.Internals
-#endif
 import           GHC.Exts
+import           GHC.Num
 import           GHC.Float              (expt)
 import           Z.Data.ASCII
 import           Z.Data.Parser.Base     (Parser, (<?>))
@@ -471,8 +469,7 @@
 sciToDouble :: Sci.Scientific -> Double
 {-# INLINABLE sciToDouble #-}
 sciToDouble sci = case c of
-#ifdef INTEGER_GMP
-    (S# i#) | (e >= FASTFLOAT_SMALLEST_POWER && e <= FASTFLOAT_LARGEST_POWER) -> unsafeDupablePerformIO $ do
+    (IS i#) | (e >= FASTFLOAT_SMALLEST_POWER && e <= FASTFLOAT_LARGEST_POWER) -> unsafeDupablePerformIO $ do
         let i = (I# i#)
             s = if i >= 0 then 0 else 1
             i' = fromIntegral $ if i >= 0 then i else (0-i)
@@ -480,7 +477,6 @@
         if success == 0
         then return $! Sci.toRealFloat sci
         else return $! r
-#endif
     _ -> Sci.toRealFloat sci
   where
     e = Sci.base10Exponent sci
diff --git a/Z/Data/Text/Base.hs b/Z/Data/Text/Base.hs
--- a/Z/Data/Text/Base.hs
+++ b/Z/Data/Text/Base.hs
@@ -137,9 +137,7 @@
 import           Data.Word
 import           Foreign.C.Types           (CSize(..))
 import           GHC.Exts
-import           GHC.Types
 import           GHC.Stack
-import           GHC.CString               (unpackCString#, unpackCStringUtf8#)
 import           Z.Data.Array
 import           Z.Data.ASCII              (c2w, pattern DOUBLE_QUOTE)
 import           Z.Data.Text.UTF8Codec
diff --git a/Z/Data/Text/Print.hs b/Z/Data/Text/Print.hs
--- a/Z/Data/Text/Print.hs
+++ b/Z/Data/Text/Print.hs
@@ -67,7 +67,6 @@
 import           Data.Int
 import           Data.List.NonEmpty             (NonEmpty (..))
 import qualified Data.Monoid                    as Monoid
-import           Data.Proxy                     (Proxy(..))
 import           Data.Ratio                     (Ratio, numerator, denominator)
 import           Data.Tagged                    (Tagged (..))
 import qualified Data.Scientific                as Sci
diff --git a/Z/Data/Text/UTF8Codec.hs b/Z/Data/Text/UTF8Codec.hs
--- a/Z/Data/Text/UTF8Codec.hs
+++ b/Z/Data/Text/UTF8Codec.hs
@@ -41,6 +41,10 @@
 encodeChar (MutablePrimArray mba#) (I# i#) (C# c#) = primitive (\ s# ->
     let !(# s1#, j# #) = encodeChar# mba# i# c# s# in (# s1#, I# j# #))
 
+writeWord8'# :: MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
+{-# INLINE writeWord8'# #-}
+writeWord8'# mba# i# w# s# = writeWord8Array# mba# i# (wordToWord8# w#) s#
+
 -- | The unboxed version of 'encodeChar'.
 --
 -- This function is marked as @NOINLINE@ to reduce code size, and stop messing up simplifier
@@ -50,37 +54,37 @@
 encodeChar# mba# i# c# = case (int2Word# (ord# c#)) of
     n#
         | isTrue# (n# `leWord#` 0x0000007F##) -> \ s# ->
-            let s1# = writeWord8Array# mba# i# n# s#
+            let s1# = writeWord8'# mba# i# n# s#
             in (# s1#, i# +# 1# #)
         | isTrue# (n# `leWord#` 0x000007FF##) -> \ s# ->
-            let s1# = writeWord8Array# mba# i# (0xC0## `or#` (n# `uncheckedShiftRL#` 6#)) s#
-                s2# = writeWord8Array# mba# (i# +# 1#) (0x80## `or#` (n# `and#` 0x3F##)) s1#
+            let s1# = writeWord8'# mba# i# (0xC0## `or#` (n# `uncheckedShiftRL#` 6#)) s#
+                s2# = writeWord8'# mba# (i# +# 1#) (0x80## `or#` (n# `and#` 0x3F##)) s1#
             in (# s2#, i# +# 2# #)
         | isTrue# (n# `leWord#` 0x0000D7FF##) -> \ s# ->
-            let s1# = writeWord8Array# mba# i# (0xE0## `or#` (n# `uncheckedShiftRL#` 12#)) s#
-                s2# = writeWord8Array# mba# (i# +# 1#) (0x80## `or#` ((n# `uncheckedShiftRL#` 6#) `and#` 0x3F##)) s1#
-                s3# = writeWord8Array# mba# (i# +# 2#) (0x80## `or#` (n# `and#` 0x3F##)) s2#
+            let s1# = writeWord8'# mba# i# (0xE0## `or#` (n# `uncheckedShiftRL#` 12#)) s#
+                s2# = writeWord8'# mba# (i# +# 1#) (0x80## `or#` ((n# `uncheckedShiftRL#` 6#) `and#` 0x3F##)) s1#
+                s3# = writeWord8'# mba# (i# +# 2#) (0x80## `or#` (n# `and#` 0x3F##)) s2#
             in (# s3#, i# +# 3# #)
         | isTrue# (n# `leWord#` 0x0000DFFF##) -> \ s# -> -- write replacement char \U+FFFD
-            let s1# = writeWord8Array# mba# i# 0xEF## s#
-                s2# = writeWord8Array# mba# (i# +# 1#) 0xBF## s1#
-                s3# = writeWord8Array# mba# (i# +# 2#) 0xBD## s2#
+            let s1# = writeWord8'# mba# i# 0xEF## s#
+                s2# = writeWord8'# mba# (i# +# 1#) 0xBF## s1#
+                s3# = writeWord8'# mba# (i# +# 2#) 0xBD## s2#
             in (# s3#, i# +# 3# #)
         | isTrue# (n# `leWord#` 0x0000FFFF##) -> \ s# ->
-            let s1# = writeWord8Array# mba# i# (0xE0## `or#` (n# `uncheckedShiftRL#` 12#)) s#
-                s2# = writeWord8Array# mba# (i# +# 1#) (0x80## `or#` ((n# `uncheckedShiftRL#` 6#) `and#` 0x3F##)) s1#
-                s3# = writeWord8Array# mba# (i# +# 2#) (0x80## `or#` (n# `and#` 0x3F##)) s2#
+            let s1# = writeWord8'# mba# i# (0xE0## `or#` (n# `uncheckedShiftRL#` 12#)) s#
+                s2# = writeWord8'# mba# (i# +# 1#) (0x80## `or#` ((n# `uncheckedShiftRL#` 6#) `and#` 0x3F##)) s1#
+                s3# = writeWord8'# mba# (i# +# 2#) (0x80## `or#` (n# `and#` 0x3F##)) s2#
             in (# s3#, i# +# 3# #)
         | isTrue# (n# `leWord#` 0x0010FFFF##) -> \ s# ->
-            let s1# = writeWord8Array# mba# i# (0xF0## `or#` (n# `uncheckedShiftRL#` 18#)) s#
-                s2# = writeWord8Array# mba# (i# +# 1#) (0x80## `or#` ((n# `uncheckedShiftRL#` 12#) `and#` 0x3F##)) s1#
-                s3# = writeWord8Array# mba# (i# +# 2#) (0x80## `or#` ((n# `uncheckedShiftRL#` 6#) `and#` 0x3F##)) s2#
-                s4# = writeWord8Array# mba# (i# +# 3#) (0x80## `or#` (n# `and#` 0x3F##)) s3#
+            let s1# = writeWord8'# mba# i# (0xF0## `or#` (n# `uncheckedShiftRL#` 18#)) s#
+                s2# = writeWord8'# mba# (i# +# 1#) (0x80## `or#` ((n# `uncheckedShiftRL#` 12#) `and#` 0x3F##)) s1#
+                s3# = writeWord8'# mba# (i# +# 2#) (0x80## `or#` ((n# `uncheckedShiftRL#` 6#) `and#` 0x3F##)) s2#
+                s4# = writeWord8'# mba# (i# +# 3#) (0x80## `or#` (n# `and#` 0x3F##)) s3#
             in (# s4#, i# +# 4# #)
         | otherwise -> \ s# -> -- write replacement char \U+FFFD
-            let s1# = writeWord8Array# mba# i#  0xEF## s#
-                s2# = writeWord8Array# mba# (i# +# 1#) 0xBF## s1#
-                s3# = writeWord8Array# mba# (i# +# 2#) 0xBD## s2#
+            let s1# = writeWord8'# mba# i#  0xEF## s#
+                s2# = writeWord8'# mba# (i# +# 1#) 0xBF## s1#
+                s3# = writeWord8'# mba# (i# +# 2#) 0xBD## s2#
             in (# s3#, i# +# 3# #)
 
 
@@ -99,26 +103,26 @@
 encodeCharModifiedUTF8# mba# i# c# = case (int2Word# (ord# c#)) of
     n#
         | isTrue# (n# `eqWord#` 0x00000000##) -> \ s# ->    -- encode \NUL as \xC0 \x80
-            let s1# = writeWord8Array# mba# i# 0xC0## s#
-                s2# = writeWord8Array# mba# (i# +# 1#) 0x80## s1#
+            let s1# = writeWord8'# mba# i# 0xC0## s#
+                s2# = writeWord8'# mba# (i# +# 1#) 0x80## s1#
             in (# s2#, i# +# 2# #)
         | isTrue# (n# `leWord#` 0x0000007F##) -> \ s# ->
-            let s1# = writeWord8Array# mba# i# n# s#
+            let s1# = writeWord8'# mba# i# n# s#
             in (# s1#, i# +# 1# #)
         | isTrue# (n# `leWord#` 0x000007FF##) -> \ s# ->
-            let s1# = writeWord8Array# mba# i# (0xC0## `or#` (n# `uncheckedShiftRL#` 6#)) s#
-                s2# = writeWord8Array# mba# (i# +# 1#) (0x80## `or#` (n# `and#` 0x3F##)) s1#
+            let s1# = writeWord8'# mba# i# (0xC0## `or#` (n# `uncheckedShiftRL#` 6#)) s#
+                s2# = writeWord8'# mba# (i# +# 1#) (0x80## `or#` (n# `and#` 0x3F##)) s1#
             in (# s2#, i# +# 2# #)
         | isTrue# (n# `leWord#` 0x0000FFFF##) -> \ s# ->    -- \xD800 ~ \xDFFF is encoded as normal UTF-8 codepoints
-            let s1# = writeWord8Array# mba# i# (0xE0## `or#` (n# `uncheckedShiftRL#` 12#)) s#
-                s2# = writeWord8Array# mba# (i# +# 1#) (0x80## `or#` ((n# `uncheckedShiftRL#` 6#) `and#` 0x3F##)) s1#
-                s3# = writeWord8Array# mba# (i# +# 2#) (0x80## `or#` (n# `and#` 0x3F##)) s2#
+            let s1# = writeWord8'# mba# i# (0xE0## `or#` (n# `uncheckedShiftRL#` 12#)) s#
+                s2# = writeWord8'# mba# (i# +# 1#) (0x80## `or#` ((n# `uncheckedShiftRL#` 6#) `and#` 0x3F##)) s1#
+                s3# = writeWord8'# mba# (i# +# 2#) (0x80## `or#` (n# `and#` 0x3F##)) s2#
             in (# s3#, i# +# 3# #)
         | otherwise -> \ s# ->
-            let s1# = writeWord8Array# mba# i# (0xF0## `or#` (n# `uncheckedShiftRL#` 18#)) s#
-                s2# = writeWord8Array# mba# (i# +# 1#) (0x80## `or#` ((n# `uncheckedShiftRL#` 12#) `and#` 0x3F##)) s1#
-                s3# = writeWord8Array# mba# (i# +# 2#) (0x80## `or#` ((n# `uncheckedShiftRL#` 6#) `and#` 0x3F##)) s2#
-                s4# = writeWord8Array# mba# (i# +# 3#) (0x80## `or#` (n# `and#` 0x3F##)) s3#
+            let s1# = writeWord8'# mba# i# (0xF0## `or#` (n# `uncheckedShiftRL#` 18#)) s#
+                s2# = writeWord8'# mba# (i# +# 1#) (0x80## `or#` ((n# `uncheckedShiftRL#` 12#) `and#` 0x3F##)) s1#
+                s3# = writeWord8'# mba# (i# +# 2#) (0x80## `or#` ((n# `uncheckedShiftRL#` 6#) `and#` 0x3F##)) s2#
+                s4# = writeWord8'# mba# (i# +# 3#) (0x80## `or#` (n# `and#` 0x3F##)) s3#
             in (# s4#, i# +# 4# #)
 
 --------------------------------------------------------------------------------
@@ -148,11 +152,11 @@
 {-# NOINLINE decodeChar# #-} -- This branchy code make GHC impossible to fuse, DON'T inline
 decodeChar# ba# idx# = case indexWord8Array# ba# idx# of
     w1#
-        | isTrue# (w1# `leWord#` 0x7F##) -> (# chr1# w1#, 1# #)
-        | isTrue# (w1# `leWord#` 0xDF##) ->
+        | isTrue# (w1# `leWord8#` (wordToWord8# 0x7F##)) -> (# chr1# w1#, 1# #)
+        | isTrue# (w1# `leWord8#` (wordToWord8# 0xDF##)) ->
             let w2# = indexWord8Array# ba# (idx# +# 1#)
             in (# chr2# w1# w2#, 2# #)
-        | isTrue# (w1# `leWord#` 0xEF##) ->
+        | isTrue# (w1# `leWord8#` (wordToWord8# 0xEF##)) ->
             let w2# = indexWord8Array# ba# (idx# +# 1#)
                 w3# = indexWord8Array# ba# (idx# +# 2#)
             in (# chr3# w1# w2# w3#, 3# #)
@@ -181,9 +185,9 @@
 {-# INLINE decodeCharLen# #-}
 decodeCharLen# ba# idx# = case indexWord8Array# ba# idx# of
     w1#
-        | isTrue# (w1# `leWord#` 0x7F##) -> 1#
-        | isTrue# (w1# `leWord#` 0xDF##) -> 2#
-        | isTrue# (w1# `leWord#` 0xEF##) -> 3#
+        | isTrue# (w1# `leWord8#` (wordToWord8# 0x7F##)) -> 1#
+        | isTrue# (w1# `leWord8#` (wordToWord8# 0xDF##)) -> 2#
+        | isTrue# (w1# `leWord8#` (wordToWord8# 0xEF##)) -> 3#
         | otherwise -> 4#
 
 -- | Decode a 'Char' from bytes in rerverse order.
@@ -256,48 +260,44 @@
 
 --------------------------------------------------------------------------------
 
-between# :: Word# -> Word# -> Word# -> Bool
-{-# INLINE between# #-}
-between# w# l# h# = isTrue# (w# `geWord#` l#) && isTrue# (w# `leWord#` h#)
-
-isContinueByte# :: Word# -> Bool
+isContinueByte# :: Word8# -> Bool
 {-# INLINE isContinueByte# #-}
-isContinueByte# w# = isTrue# (and# w# 0xC0## `eqWord#` 0x80##)
+isContinueByte# w# = isTrue# (and# (word8ToWord# w#) 0xC0## `eqWord#` 0x80##)
 
-chr1# :: Word# -> Char#
+chr1# :: Word8# -> Char#
 {-# INLINE chr1# #-}
 chr1# x1# = chr# y1#
   where
-    !y1# = word2Int# x1#
+    !y1# = word2Int# (word8ToWord# x1#)
 
-chr2# :: Word# -> Word# -> Char#
+chr2# :: Word8# -> Word8# -> Char#
 {-# INLINE chr2# #-}
 chr2# x1# x2# = chr# (z1# +# z2#)
   where
-    !y1# = word2Int# x1#
-    !y2# = word2Int# x2#
+    !y1# = word2Int# (word8ToWord# x1#)
+    !y2# = word2Int# (word8ToWord# x2#)
     !z1# = uncheckedIShiftL# (y1# -# 0xC0#) 6#
     !z2# = y2# -# 0x80#
 
-chr3# :: Word# -> Word# -> Word# -> Char#
+chr3# :: Word8# -> Word8# -> Word8# -> Char#
 {-# INLINE chr3# #-}
 chr3# x1# x2# x3# = chr# (z1# +# z2# +# z3#)
   where
-    !y1# = word2Int# x1#
-    !y2# = word2Int# x2#
-    !y3# = word2Int# x3#
+    !y1# = word2Int# (word8ToWord# x1#)
+    !y2# = word2Int# (word8ToWord# x2#)
+    !y3# = word2Int# (word8ToWord# x3#)
     !z1# = uncheckedIShiftL# (y1# -# 0xE0#) 12#
     !z2# = uncheckedIShiftL# (y2# -# 0x80#) 6#
     !z3# = y3# -# 0x80#
 
-chr4# :: Word# -> Word# -> Word# -> Word# -> Char#
+chr4# :: Word8# -> Word8# -> Word8# -> Word8# -> Char#
 {-# INLINE chr4# #-}
 chr4# x1# x2# x3# x4# = chr# (z1# +# z2# +# z3# +# z4#)
   where
-    !y1# = word2Int# x1#
-    !y2# = word2Int# x2#
-    !y3# = word2Int# x3#
-    !y4# = word2Int# x4#
+    !y1# = word2Int# (word8ToWord# x1#)
+    !y2# = word2Int# (word8ToWord# x2#)
+    !y3# = word2Int# (word8ToWord# x3#)
+    !y4# = word2Int# (word8ToWord# x4#)
     !z1# = uncheckedIShiftL# (y1# -# 0xF0#) 18#
     !z2# = uncheckedIShiftL# (y2# -# 0x80#) 12#
     !z3# = uncheckedIShiftL# (y3# -# 0x80#) 6#
diff --git a/Z/Data/Vector/Base.hs b/Z/Data/Vector/Base.hs
--- a/Z/Data/Vector/Base.hs
+++ b/Z/Data/Vector/Base.hs
@@ -107,7 +107,6 @@
 import           Foreign.C
 import           GHC.Exts
 import           GHC.Stack
-import           GHC.CString
 import           GHC.Word
 import           Prelude                        hiding (concat, concatMap, mapM, mapM_,
                                                 elem, notElem, null, length, map,
@@ -267,7 +266,7 @@
     {-# INLINE mempty #-}
     mempty  = empty
     {-# INLINE mappend #-}
-    mappend = append
+    mappend = (<>)
     {-# INLINE mconcat #-}
     mconcat = concat
 
@@ -505,7 +504,7 @@
     {-# INLINE mempty #-}
     mempty  = empty
     {-# INLINE mappend #-}
-    mappend = append
+    mappend = (<>)
     {-# INLINE mconcat #-}
     mconcat = concat
 
diff --git a/Z/Data/Vector/FlatIntMap.hs b/Z/Data/Vector/FlatIntMap.hs
--- a/Z/Data/Vector/FlatIntMap.hs
+++ b/Z/Data/Vector/FlatIntMap.hs
@@ -74,7 +74,7 @@
 
 instance Monoid.Monoid (FlatIntMap v) where
     {-# INLINE mappend #-}
-    mappend = merge
+    mappend = (<>)
     {-# INLINE mempty #-}
     mempty = empty
 
diff --git a/Z/Data/Vector/FlatIntSet.hs b/Z/Data/Vector/FlatIntSet.hs
--- a/Z/Data/Vector/FlatIntSet.hs
+++ b/Z/Data/Vector/FlatIntSet.hs
@@ -60,7 +60,7 @@
 
 instance Monoid.Monoid FlatIntSet where
     {-# INLINE mappend #-}
-    mappend = merge
+    mappend = (<>)
     {-# INLINE mempty #-}
     mempty = empty
 
diff --git a/Z/Data/Vector/FlatMap.hs b/Z/Data/Vector/FlatMap.hs
--- a/Z/Data/Vector/FlatMap.hs
+++ b/Z/Data/Vector/FlatMap.hs
@@ -74,7 +74,7 @@
 
 instance Ord k => Monoid.Monoid (FlatMap k v) where
     {-# INLINE mappend #-}
-    mappend = merge
+    mappend = (<>)
     {-# INLINE mempty #-}
     mempty = empty
 
diff --git a/Z/Data/Vector/FlatSet.hs b/Z/Data/Vector/FlatSet.hs
--- a/Z/Data/Vector/FlatSet.hs
+++ b/Z/Data/Vector/FlatSet.hs
@@ -60,7 +60,7 @@
 
 instance Ord v => Monoid.Monoid (FlatSet v) where
     {-# INLINE mappend #-}
-    mappend = merge
+    mappend = (<>)
     {-# INLINE mempty #-}
     mempty = empty
 
diff --git a/Z/Foreign/CPtr.hs b/Z/Foreign/CPtr.hs
--- a/Z/Foreign/CPtr.hs
+++ b/Z/Foreign/CPtr.hs
@@ -118,18 +118,10 @@
 -- so it may be optimized away, 'withCPtrForever' solves that.
 --
 withCPtrForever :: CPtr a -> (Ptr a -> IO b) -> IO b
-#if MIN_VERSION_base(4,15,0)
 {-# INLINABLE withCPtrForever #-}
 withCPtrForever (CPtr pa@(PrimArray ba#)) f = IO $ \ s ->
     case f (indexPrimArray pa 0) of
         IO action# -> keepAlive# ba# s action#
-#else
-{-# NOINLINE withCPtrForever #-}
-withCPtrForever (CPtr pa@(PrimArray ba#)) f = do
-    r <- f (indexPrimArray pa 0)
-    primitive_ (touch# ba#)
-    return r
-#endif
 
 -- | Pass a list of 'CPtr Foo' as @foo**@. USE THIS FUNCTION WITH UNSAFE FFI ONLY!
 withCPtrsUnsafe :: forall a b. [CPtr a] -> (BA# (Ptr a) -> Int -> IO b) -> IO b
