    -- |
    -- Module      : Data.Memory.Internal.CompatPrim
    -- License     : BSD-style
    -- Maintainer  : Vincent Hanquez <vincent@snarc.org>
    -- Stability   : stable
    -- Portability : Compat
    --
    -- This module try to keep all the difference between versions of ghc primitive
    -- or other needed packages, so that modules don't need to use CPP.
    --
    -- Note that MagicHash and CPP conflicts in places, making it "more interesting"
    -- to write compat code for primitives
    --
    {-# LANGUAGE CPP #-}
    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE MagicHash #-}
    {-# LANGUAGE UnboxedTuples #-}
    #include "MachDeps.h"
    module Data.Memory.Internal.CompatPrim64
        ( Word64#
        , Int64#
        , eqInt64#
        , neInt64#
        , ltInt64#
        , leInt64#
        , gtInt64#
        , geInt64#
        , quotInt64#
        , remInt64#
        , eqWord64#
        , neWord64#
        , ltWord64#
        , leWord64#
        , gtWord64#
        , geWord64#
        , and64#
        , or64#
        , xor64#
        , not64#
        , timesWord64#
        , uncheckedShiftL64#
        , uncheckedShiftRL64#

        , int64ToWord64#
        , word64ToInt64#
        , intToInt64#
        , int64ToInt#
        , wordToWord64#
        , word64ToWord#
        , w64#
        ) where

    #if WORD_SIZE_IN_BITS == 64
    import GHC.Prim hiding (Word64#, Int64#)

    #if __GLASGOW_HASKELL__ >= 708
    type OutBool = Int#
    #else
    type OutBool = Bool
    #endif

    type Word64# = Word#
    type Int64# = Int#

    #if __GLASGOW_HASKELL__ < 904
    eqWord64# :: Word64# -> Word64# -> OutBool
    eqWord64# = eqWord#

    neWord64# :: Word64# -> Word64# -> OutBool
    neWord64# = neWord#

    ltWord64# :: Word64# -> Word64# -> OutBool
    ltWord64# = ltWord#

    leWord64# :: Word64# -> Word64# -> OutBool
    leWord64# = leWord#

    gtWord64# :: Word64# -> Word64# -> OutBool
    gtWord64# = gtWord#

    geWord64# :: Word64# -> Word64# -> OutBool
    geWord64# = geWord#

    eqInt64# :: Int64# -> Int64# -> OutBool
    eqInt64# = (==#)

    neInt64# :: Int64# -> Int64# -> OutBool
    neInt64# = (/=#)

    ltInt64# :: Int64# -> Int64# -> OutBool
    ltInt64# = (<#)

    leInt64# :: Int64# -> Int64# -> OutBool
    leInt64# = (<=#)

    gtInt64# :: Int64# -> Int64# -> OutBool
    gtInt64# = (>#)

    geInt64# :: Int64# -> Int64# -> OutBool
    geInt64# = (<=#)

    quotInt64# :: Int64# -> Int64# -> Int64#
    quotInt64# = quotInt#

    remInt64# :: Int64# -> Int64# -> Int64#
    remInt64# = remInt#

    and64# :: Word64# -> Word64# -> Word64#
    and64# = and#

    or64# :: Word64# -> Word64# -> Word64#
    or64# = or#

    xor64# :: Word64# -> Word64# -> Word64#
    xor64# = xor#

    not64# :: Word64# -> Word64#
    not64# = not#

    uncheckedShiftL64# :: Word64# -> Int# -> Word64#
    uncheckedShiftL64# = uncheckedShiftL#

    uncheckedShiftRL64#  :: Word64# -> Int# -> Word64#
    uncheckedShiftRL64# = uncheckedShiftL#

    int64ToWord64# :: Int64# -> Word64#
    int64ToWord64# = int2Word#

    word64ToInt64# :: Word64# -> Int64#
    word64ToInt64# = word2Int#

    intToInt64# :: Int# -> Int64#
    intToInt64# w = w

    int64ToInt# :: Int64# -> Int#
    int64ToInt# w = w

    wordToWord64# :: Word# -> Word64#
    wordToWord64# w = w

    word64ToWord# :: Word64# -> Word#
    word64ToWord# w = w

    timesWord64# :: Word64# -> Word64# -> Word64#
    timesWord64# = timesWord#
    #endif

    w64# :: Word# -> Word# -> Word# -> Word64#
    w64# :: Word# -> Word# -> Word# -> Word#
    w64# Word#
    w Word#
    _ Word#
    _ = Word#
    w

    #elif WORD_SIZE_IN_BITS == 32
    import GHC.IntWord64
    import GHC.Prim (Word#)

    timesWord64# :: Word64# -> Word64# -> Word64#
    timesWord64# a b =
        let !ai = word64ToInt64# a
            !bi = word64ToInt64# b
         in int64ToWord64# (timesInt64# ai bi)

    w64# :: Word# -> Word# -> Word# -> Word64#
    w64# _ hw lw =
        let !h = wordToWord64# hw
            !l = wordToWord64# lw
         in or64# (uncheckedShiftL64# h 32#) l
    #else
    #error "not a supported architecture. supported WORD_SIZE_IN_BITS is 32 bits or 64 bits"
    #endif