    {-# LANGUAGE CPP #-}
    {-# LANGUAGE NoImplicitPrelude #-}
    {-# LANGUAGE BangPatterns #-}
    {-# LANGUAGE MagicHash #-}
    {-# LANGUAGE UnboxedTuples #-}
    {-# LANGUAGE UnliftedFFITypes #-}
    {-# LANGUAGE NegativeLiterals #-}
    {-# LANGUAGE ExplicitForAll #-}
    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE BlockArguments #-}
    {-# LANGUAGE BinaryLiterals #-}
    {-# OPTIONS_GHC -fexpose-all-unfoldings #-}

    module GHC.Num.Primitives
       (
       -- * Bool#
       Bool#
       , (&&#)
       , (||#)
       , notB#
       -- * Int#
       , testBitI#
       , minI#
       , maxI#
       , sgnI#
       , absI#
       , cmpI#
       , intEncodeDouble#
       , popCntI#
       -- * Word#
       , andNot#
       , cmpW#
       , bitW#
       , maxW#
       , minW#
       , testBitW#
       , shiftRW#
       , plusWord3#
       , plusWord12#
       , quotRemWord3#
       , wordFromAbsInt#
       , wordLog2#
       , wordLogBase#
       , wordSizeInBase#
       , wordIsPowerOf2#
       , wordEncodeDouble#
       , wordReverseBits#
       , wordReverseBits32#
       , wordReverseBytes#
       -- ** Addr import/export
       , wordFromAddr#
       , wordFromAddrLE#
       , wordFromAddrBE#
       , wordToAddr#
       , wordToAddrLE#
       , wordToAddrBE#
       , wordWriteAddrLE#
       , wordWriteAddrBE#
       -- ** ByteArray import/export
       , wordFromByteArray#
       , wordFromByteArrayLE#
       , wordFromByteArrayBE#
       , wordToMutableByteArray#
       , wordToMutableByteArrayLE#
       , wordToMutableByteArrayBE#
       , wordWriteMutableByteArrayLE#
       , wordWriteMutableByteArrayBE#
       -- * Exception
       , raiseUnderflow
       , raiseUnderflow_Word#
       , raiseDivZero
       , raiseDivZero_Word#
       , unexpectedValue
       , unexpectedValue_Int#
       , unexpectedValue_Word#
       -- * IO
       , ioWord#
       , ioInt#
       , ioVoid
       , ioBool
       )
    where

    #include "MachDeps.h"
    #include "WordSize.h"

    -- Required for WORDS_BIGENDIAN
    #include <ghcautoconf.h>

    #if (__GLASGOW_HASKELL__ < 811)
    import GHC.Magic
    #else
    import GHC.Prim.Exception
    #endif

    import GHC.Prim
    import GHC.Types
    import GHC.Tuple () -- See Note [Depend on GHC.Tuple] in GHC.Base

    default ()

    ----------------------------------
    -- Bool#
    ----------------------------------

    type Bool# = Int#

    (&&#) :: Bool# -> Bool# -> Bool#
    &&# :: Bool# -> Bool# -> Bool#
    (&&#) = Bool# -> Bool# -> Bool#
    andI#

    (||#) :: Bool# -> Bool# -> Bool#
    ||# :: Bool# -> Bool# -> Bool#
    (||#) = Bool# -> Bool# -> Bool#
    orI#

    notB# :: Bool# -> Bool#
    notB# :: Bool# -> Bool#
    notB# Bool#
    x = Bool#
    x Bool# -> Bool# -> Bool#
    `xorI#` Bool#
    1#

    infixr 3  &&#
    infixr 2  ||#

    ----------------------------------
    -- Int#
    ----------------------------------

    -- | Branchless `abs`
    absI# :: Int# -> Int#
    absI# :: Bool# -> Bool#
    absI# Bool#
    i# = (Bool#
    i# Bool# -> Bool# -> Bool#
    `xorI#` Bool#
    nsign) Bool# -> Bool# -> Bool#
    -# Bool#
    nsign
      where
        -- nsign = negateInt# (i# <# 0#)
        nsign :: Bool#
    nsign = Bool# -> Bool# -> Bool#
    uncheckedIShiftRA# Bool#
    i# (WORD_SIZE_IN_BITS# -# 1#)

    -- | Branchless `signum`
    sgnI# :: Int# -> Int#
    sgnI# :: Bool# -> Bool#
    sgnI# Bool#
    x# = (Bool#
    x# Bool# -> Bool# -> Bool#
    ># Bool#
    0#) Bool# -> Bool# -> Bool#
    -# (Bool#
    x# Bool# -> Bool# -> Bool#
    <# Bool#
    0#)

    -- | Population count
    popCntI# :: Int# -> Word#
    popCntI# :: Bool# -> Word#
    popCntI# Bool#
    i = Word# -> Word#
    popCnt# (Bool# -> Word#
    int2Word# Bool#
    i)

    -- | Branchless comparison
    cmpI# :: Int# -> Int# -> Int#
    cmpI# :: Bool# -> Bool# -> Bool#
    cmpI# Bool#
    x# Bool#
    y# = (Bool#
    x# Bool# -> Bool# -> Bool#
    ># Bool#
    y#) Bool# -> Bool# -> Bool#
    -# (Bool#
    x# Bool# -> Bool# -> Bool#
    <# Bool#
    y#)

    testBitI# :: Int# -> Word# -> Bool#
    testBitI# :: Bool# -> Word# -> Bool#
    testBitI# Bool#
    x Word#
    i = ((Bool# -> Bool# -> Bool#
    uncheckedIShiftL# Bool#
    1# (Word# -> Bool#
    word2Int# Word#
    i)) Bool# -> Bool# -> Bool#
    `andI#` Bool#
    x) Bool# -> Bool# -> Bool#
    /=# Bool#
    0#

    minI# :: Int# -> Int# -> Int#
    minI# :: Bool# -> Bool# -> Bool#
    minI# Bool#
    x Bool#
    y | Bool# -> Bool
    isTrue# (Bool#
    x Bool# -> Bool# -> Bool#
    <=# Bool#
    y) = Bool#
    x
              | Bool
    True              = Bool#
    y

    maxI# :: Int# -> Int# -> Int#
    maxI# :: Bool# -> Bool# -> Bool#
    maxI# Bool#
    x Bool#
    y | Bool# -> Bool
    isTrue# (Bool#
    x Bool# -> Bool# -> Bool#
    >=# Bool#
    y) = Bool#
    x
              | Bool
    True              = Bool#
    y

    -- | Encode (# Int# mantissa, Int# exponent #) into a Double#.
    --
    -- (provided by GHC's RTS)
    foreign import ccall unsafe "__int_encodeDouble"
       intEncodeDouble# :: Int# -> Int# -> Double#

    ----------------------------------
    -- Word#
    ----------------------------------

    andNot# :: Word# -> Word# -> Word#
    andNot# :: Word# -> Word# -> Word#
    andNot# Word#
    x Word#
    y = Word#
    x Word# -> Word# -> Word#
    `and#` (Word# -> Word#
    not# Word#
    y)

    cmpW# :: Word# -> Word# -> Ordering
    {-# INLINE cmpW# #-}
    cmpW# :: Word# -> Word# -> Ordering
    cmpW# Word#
    x# Word#
    y#
      | Bool# -> Bool
    isTrue# (Word#
    x# Word# -> Word# -> Bool#
    `ltWord#` Word#
    y#) = Ordering
    LT
      | Bool# -> Bool
    isTrue# (Word#
    x# Word# -> Word# -> Bool#
    `eqWord#` Word#
    y#) = Ordering
    EQ
      | Bool
    True                      = Ordering
    GT

    -- | Return the absolute value of the Int# in a Word#
    wordFromAbsInt# :: Int# -> Word#
    wordFromAbsInt# :: Bool# -> Word#
    wordFromAbsInt# Bool#
    i
       | Bool# -> Bool
    isTrue# (Bool#
    i Bool# -> Bool# -> Bool#
    >=# Bool#
    0#) = Bool# -> Word#
    int2Word# Bool#
    i
       | Bool
    True               = Bool# -> Word#
    int2Word# (Bool# -> Bool#
    negateInt# Bool#
    i)

    minW# :: Word# -> Word# -> Word#
    minW# :: Word# -> Word# -> Word#
    minW# Word#
    x# Word#
    y# | Bool# -> Bool
    isTrue# (Word#
    x# Word# -> Word# -> Bool#
    `leWord#` Word#
    y#) = Word#
    x#
                | Bool
    True                      = Word#
    y#

    maxW# :: Word# -> Word# -> Word#
    maxW# :: Word# -> Word# -> Word#
    maxW# Word#
    x# Word#
    y# | Bool# -> Bool
    isTrue# (Word#
    x# Word# -> Word# -> Bool#
    `gtWord#` Word#
    y#) = Word#
    x#
                | Bool
    True                      = Word#
    y#

    bitW# :: Int# -> Word#
    bitW# :: Bool# -> Word#
    bitW# Bool#
    k = Word#
    1## Word# -> Bool# -> Word#
    `uncheckedShiftL#` Bool#
    k

    testBitW# :: Word# -> Word# -> Bool#
    testBitW# :: Word# -> Word# -> Bool#
    testBitW# Word#
    w Word#
    k = Word#
    w Word# -> Word# -> Word#
    `and#` (Word#
    1## Word# -> Bool# -> Word#
    `uncheckedShiftL#` Word# -> Bool#
    word2Int# Word#
    k) Word# -> Word# -> Bool#
    `neWord#` Word#
    0##

    -- | Safe right shift for Word#
    shiftRW# :: Word# -> Word# -> Word#
    shiftRW# :: Word# -> Word# -> Word#
    shiftRW# Word#
    a Word#
    b
       | Bool# -> Bool
    isTrue# (Word#
    b Word# -> Word# -> Bool#
    `geWord#` WORD_SIZE_IN_BITS##) = 0##
       | Bool
    True                                      = Word#
    a Word# -> Bool# -> Word#
    `uncheckedShiftRL#` (Word# -> Bool#
    word2Int# Word#
    b)

    -- | (h,l) <- a + (hb,lb)
    plusWord12# :: Word# -> (# Word#,Word# #) -> (# Word#,Word# #)
    {-# INLINABLE plusWord12# #-}
    plusWord12# :: Word# -> (# Word#, Word# #) -> (# Word#, Word# #)
    plusWord12# Word#
    a0 (# Word#
    b1,Word#
    b0 #) = (# Word#
    m1, Word#
    m0 #)
       where
          !(# Word#
    t, Word#
    m0 #) = Word# -> Word# -> (# Word#, Word# #)
    plusWord2# Word#
    a0 Word#
    b0
          !m1 :: Word#
    m1          = Word# -> Word# -> Word#
    plusWord# Word#
    t Word#
    b1

    -- | Add 3 values together
    plusWord3# :: Word# -> Word# -> Word# -> (# Word#, Word# #)
    {-# INLINABLE plusWord3# #-}
    plusWord3# :: Word# -> Word# -> Word# -> (# Word#, Word# #)
    plusWord3# Word#
    a Word#
    b Word#
    c = (# Word#
    r1, Word#
    r0 #)
       where
          !(# Word#
    t1, Word#
    t0 #) = Word# -> Word# -> (# Word#, Word# #)
    plusWord2# Word#
    a Word#
    b
          !(# Word#
    t2, Word#
    r0 #) = Word# -> Word# -> (# Word#, Word# #)
    plusWord2# Word#
    t0 Word#
    c
          !r1 :: Word#
    r1           = Word# -> Word# -> Word#
    plusWord# Word#
    t1 Word#
    t2

    -- | 2-by-1 large division
    --
    -- Requires:
    --    b0 /= 0
    --    a1 >= b0 (not required, but if not q1=0)
    quotRemWord3# :: (# Word#,Word# #) -> Word# -> (# (# Word#,Word# #),Word# #)
    quotRemWord3# :: (# Word#, Word# #) -> Word# -> (# (# Word#, Word# #), Word# #)
    quotRemWord3# (# Word#
    a1,Word#
    a0 #) Word#
    b0 = (# (# Word#
    q1, Word#
    q0 #), Word#
    r0 #)
       where
          !(# Word#
    q1, Word#
    r' #) = Word# -> Word# -> (# Word#, Word# #)
    quotRemWord# Word#
    a1 Word#
    b0
          !(# Word#
    q0, Word#
    r0 #) = Word# -> Word# -> Word# -> (# Word#, Word# #)
    quotRemWord2# Word#
    r' Word#
    a0 Word#
    b0

    -- | Encode (# Word# mantissa, Int# exponent #) into a Double#.
    --
    -- (provided by GHC's RTS)
    foreign import ccall unsafe "__word_encodeDouble"
       wordEncodeDouble# :: Word# -> Int# -> Double#

    -- | Compute base-2 log of 'Word#'
    --
    -- This is internally implemented as count-leading-zeros machine instruction.
    wordLog2# :: Word# -> Word#
    wordLog2# :: Word# -> Word#
    wordLog2# Word#
    w   = (WORD_SIZE_IN_BITS## `minusWord#` 1##) `minusWord#` (clz# w)

    -- | Logarithm for an arbitrary base
    wordLogBase# :: Word# -> Word# -> Word#
    wordLogBase# :: Word# -> Word# -> Word#
    wordLogBase# Word#
    base Word#
    a
       | Bool# -> Bool
    isTrue# (Word#
    base Word# -> Word# -> Bool#
    `leWord#` Word#
    1##)
       = (# #) -> Word#
    unexpectedValue_Word# (# #)

       | Word#
    2## <- Word#
    base
       = Word# -> Word#
    wordLog2# Word#
    a

       | Bool
    True
       = case Word# -> (# Word#, Word# #)
    go Word#
    base of (# Word#
    _, Word#
    e' #) -> Word#
    e'
       where
          goSqr :: Word# -> (# Word#, Word# #)
    goSqr Word#
    pw = case Word# -> Word# -> (# Word#, Word# #)
    timesWord2# Word#
    pw Word#
    pw of
             (# Word#
    0##, Word#
    l #) -> Word# -> (# Word#, Word# #)
    go Word#
    l
             (# Word#
    _  , Word#
    _ #) -> (# Word#
    a, Word#
    0## #)
          go :: Word# -> (# Word#, Word# #)
    go Word#
    pw = if Bool# -> Bool
    isTrue# (Word#
    a Word# -> Word# -> Bool#
    `ltWord#` Word#
    pw)
             then (# Word#
    a, Word#
    0## #)
             else case Word# -> (# Word#, Word# #)
    goSqr Word#
    pw of
                (# Word#
    q, Word#
    e #) -> if Bool# -> Bool
    isTrue# (Word#
    q Word# -> Word# -> Bool#
    `ltWord#` Word#
    pw)
                   then (# Word#
    q, Word#
    2## Word# -> Word# -> Word#
    `timesWord#` Word#
    e #)
                   else (# Word#
    q Word# -> Word# -> Word#
    `quotWord#` Word#
    pw
                        , Word#
    2## Word# -> Word# -> Word#
    `timesWord#` Word#
    e Word# -> Word# -> Word#
    `plusWord#` Word#
    1## #)

    wordSizeInBase# :: Word# -> Word# -> Word#
    wordSizeInBase# :: Word# -> Word# -> Word#
    wordSizeInBase# Word#
    _    Word#
    0## = Word#
    0##
    wordSizeInBase# Word#
    base Word#
    w   = Word#
    1## Word# -> Word# -> Word#
    `plusWord#` Word# -> Word# -> Word#
    wordLogBase# Word#
    base Word#
    w

    -- | Indicate if the value is a power of two and which one
    wordIsPowerOf2# :: Word# -> (# (# #) | Word# #)
    wordIsPowerOf2# :: Word# -> (# (# #) | Word# #)
    wordIsPowerOf2# Word#
    w
       | Bool# -> Bool
    isTrue# (Word# -> Word#
    popCnt# Word#
    w Word# -> Word# -> Bool#
    `neWord#` Word#
    1##) = (# (# #) | #)
       | Bool
    True                              = (# | Word# -> Word#
    ctz# Word#
    w #)

    -- | Reverse bytes in a Word#
    wordReverseBytes# :: Word# -> Word#
    wordReverseBytes# :: Word# -> Word#
    wordReverseBytes# Word#
    x0 = Word#
    r
       where
    #if WORD_SIZE_IN_BITS == 64
          x1 :: Word#
    x1 = ((Word#
    x0 Word# -> Word# -> Word#
    `and#` Word#
    0x00FF00FF00FF00FF##) Word# -> Bool# -> Word#
    `uncheckedShiftL#`  Bool#
    8#) Word# -> Word# -> Word#
    `or#` ((Word#
    x0 Word# -> Word# -> Word#
    `and#` Word#
    0xFF00FF00FF00FF00##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#`  Bool#
    8#)
          x2 :: Word#
    x2 = ((Word#
    x1 Word# -> Word# -> Word#
    `and#` Word#
    0x0000FFFF0000FFFF##) Word# -> Bool# -> Word#
    `uncheckedShiftL#` Bool#
    16#) Word# -> Word# -> Word#
    `or#` ((Word#
    x1 Word# -> Word# -> Word#
    `and#` Word#
    0xFFFF0000FFFF0000##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#` Bool#
    16#)
          r :: Word#
    r  = ((Word#
    x2 Word# -> Word# -> Word#
    `and#` Word#
    0x00000000FFFFFFFF##) Word# -> Bool# -> Word#
    `uncheckedShiftL#` Bool#
    32#) Word# -> Word# -> Word#
    `or#` ((Word#
    x2 Word# -> Word# -> Word#
    `and#` Word#
    0xFFFFFFFF00000000##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#` Bool#
    32#)
    #else
          x1 = ((x0 `and#` 0x00FF00FF##) `uncheckedShiftL#`  8#) `or#` ((x0 `and#` 0xFF00FF00##) `uncheckedShiftRL#`  8#)
          r  = ((x1 `and#` 0x0000FFFF##) `uncheckedShiftL#` 16#) `or#` ((x1 `and#` 0xFFFF0000##) `uncheckedShiftRL#` 16#)
    #endif

    -- | Reverse bits in a Word#
    wordReverseBits# :: Word# -> Word#
    wordReverseBits# :: Word# -> Word#
    wordReverseBits# Word#
    x0 = Word#
    r
       where
    #if WORD_SIZE_IN_BITS == 64
          x1 :: Word#
    x1 = ((Word#
    x0 Word# -> Word# -> Word#
    `and#` Word#
    0x5555555555555555##) Word# -> Bool# -> Word#
    `uncheckedShiftL#`  Bool#
    1#) Word# -> Word# -> Word#
    `or#` ((Word#
    x0 Word# -> Word# -> Word#
    `and#` Word#
    0xAAAAAAAAAAAAAAAA##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#`  Bool#
    1#)
          x2 :: Word#
    x2 = ((Word#
    x1 Word# -> Word# -> Word#
    `and#` Word#
    0x3333333333333333##) Word# -> Bool# -> Word#
    `uncheckedShiftL#`  Bool#
    2#) Word# -> Word# -> Word#
    `or#` ((Word#
    x1 Word# -> Word# -> Word#
    `and#` Word#
    0xCCCCCCCCCCCCCCCC##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#`  Bool#
    2#)
          x3 :: Word#
    x3 = ((Word#
    x2 Word# -> Word# -> Word#
    `and#` Word#
    0x0F0F0F0F0F0F0F0F##) Word# -> Bool# -> Word#
    `uncheckedShiftL#`  Bool#
    4#) Word# -> Word# -> Word#
    `or#` ((Word#
    x2 Word# -> Word# -> Word#
    `and#` Word#
    0xF0F0F0F0F0F0F0F0##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#`  Bool#
    4#)
          x4 :: Word#
    x4 = ((Word#
    x3 Word# -> Word# -> Word#
    `and#` Word#
    0x00FF00FF00FF00FF##) Word# -> Bool# -> Word#
    `uncheckedShiftL#`  Bool#
    8#) Word# -> Word# -> Word#
    `or#` ((Word#
    x3 Word# -> Word# -> Word#
    `and#` Word#
    0xFF00FF00FF00FF00##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#`  Bool#
    8#)
          x5 :: Word#
    x5 = ((Word#
    x4 Word# -> Word# -> Word#
    `and#` Word#
    0x0000FFFF0000FFFF##) Word# -> Bool# -> Word#
    `uncheckedShiftL#` Bool#
    16#) Word# -> Word# -> Word#
    `or#` ((Word#
    x4 Word# -> Word# -> Word#
    `and#` Word#
    0xFFFF0000FFFF0000##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#` Bool#
    16#)
          r :: Word#
    r  = ((Word#
    x5 Word# -> Word# -> Word#
    `and#` Word#
    0x00000000FFFFFFFF##) Word# -> Bool# -> Word#
    `uncheckedShiftL#` Bool#
    32#) Word# -> Word# -> Word#
    `or#` ((Word#
    x5 Word# -> Word# -> Word#
    `and#` Word#
    0xFFFFFFFF00000000##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#` Bool#
    32#)
    #else
          x1 = ((x0 `and#` 0x55555555##) `uncheckedShiftL#`  1#) `or#` ((x0 `and#` 0xAAAAAAAA##) `uncheckedShiftRL#`  1#)
          x2 = ((x1 `and#` 0x33333333##) `uncheckedShiftL#`  2#) `or#` ((x1 `and#` 0xCCCCCCCC##) `uncheckedShiftRL#`  2#)
          x3 = ((x2 `and#` 0x0F0F0F0F##) `uncheckedShiftL#`  4#) `or#` ((x2 `and#` 0xF0F0F0F0##) `uncheckedShiftRL#`  4#)
          x4 = ((x3 `and#` 0x00FF00FF##) `uncheckedShiftL#`  8#) `or#` ((x3 `and#` 0xFF00FF00##) `uncheckedShiftRL#`  8#)
          r  = ((x4 `and#` 0x0000FFFF##) `uncheckedShiftL#` 16#) `or#` ((x4 `and#` 0xFFFF0000##) `uncheckedShiftRL#` 16#)
    #endif

    -- | Reverse bits in the Word32 subwords composing a Word#
    wordReverseBits32# :: Word# -> Word#
    #if WORD_SIZE_IN_BITS == 64
    wordReverseBits32# :: Word# -> Word#
    wordReverseBits32# Word#
    x0 = Word#
    r
       where
          x1 :: Word#
    x1 = ((Word#
    x0 Word# -> Word# -> Word#
    `and#` Word#
    0x5555555555555555##) Word# -> Bool# -> Word#
    `uncheckedShiftL#`  Bool#
    1#) Word# -> Word# -> Word#
    `or#` ((Word#
    x0 Word# -> Word# -> Word#
    `and#` Word#
    0xAAAAAAAAAAAAAAAA##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#`  Bool#
    1#)
          x2 :: Word#
    x2 = ((Word#
    x1 Word# -> Word# -> Word#
    `and#` Word#
    0x3333333333333333##) Word# -> Bool# -> Word#
    `uncheckedShiftL#`  Bool#
    2#) Word# -> Word# -> Word#
    `or#` ((Word#
    x1 Word# -> Word# -> Word#
    `and#` Word#
    0xCCCCCCCCCCCCCCCC##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#`  Bool#
    2#)
          x3 :: Word#
    x3 = ((Word#
    x2 Word# -> Word# -> Word#
    `and#` Word#
    0x0F0F0F0F0F0F0F0F##) Word# -> Bool# -> Word#
    `uncheckedShiftL#`  Bool#
    4#) Word# -> Word# -> Word#
    `or#` ((Word#
    x2 Word# -> Word# -> Word#
    `and#` Word#
    0xF0F0F0F0F0F0F0F0##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#`  Bool#
    4#)
          x4 :: Word#
    x4 = ((Word#
    x3 Word# -> Word# -> Word#
    `and#` Word#
    0x00FF00FF00FF00FF##) Word# -> Bool# -> Word#
    `uncheckedShiftL#`  Bool#
    8#) Word# -> Word# -> Word#
    `or#` ((Word#
    x3 Word# -> Word# -> Word#
    `and#` Word#
    0xFF00FF00FF00FF00##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#`  Bool#
    8#)
          r :: Word#
    r  = ((Word#
    x4 Word# -> Word# -> Word#
    `and#` Word#
    0x0000FFFF0000FFFF##) Word# -> Bool# -> Word#
    `uncheckedShiftL#` Bool#
    16#) Word# -> Word# -> Word#
    `or#` ((Word#
    x4 Word# -> Word# -> Word#
    `and#` Word#
    0xFFFF0000FFFF0000##) Word# -> Bool# -> Word#
    `uncheckedShiftRL#` Bool#
    16#)
    #else
    wordReverseBits32# x0 = wordReverseBits# x0
    #endif

    -- | Write a Word to @/addr/@ in base-256 little-endian representation and
    -- return the number of bytes written.
    wordToAddrLE# :: Word# -> Addr# -> State# s -> (# State# s, Word# #)
    wordToAddrLE# :: forall s. Word# -> Addr# -> State# s -> (# State# s, Word# #)
    wordToAddrLE# Word#
    x Addr#
    addr = Word# -> Bool# -> State# s -> (# State# s, Word# #)
    forall {d}. Word# -> Bool# -> State# d -> (# State# d, Word# #)
    go Word#
    x Bool#
    0#
       where
          go :: Word# -> Bool# -> State# d -> (# State# d, Word# #)
    go Word#
    w Bool#
    c State# d
    s
             | Word#
    0## <- Word#
    w
             = (# State# d
    s, Bool# -> Word#
    int2Word# Bool#
    c #)

             | Bool
    True
             = case Addr# -> Bool# -> Word8# -> State# d -> State# d
    forall d. Addr# -> Bool# -> Word8# -> State# d -> State# d
    writeWord8OffAddr# Addr#
    addr Bool#
    c (Word# -> Word8#
    wordToWord8# Word#
    w) State# d
    s of
                State# d
    s' -> Word# -> Bool# -> State# d -> (# State# d, Word# #)
    go (Word#
    w Word# -> Bool# -> Word#
    `uncheckedShiftRL#` Bool#
    8#) (Bool#
    c Bool# -> Bool# -> Bool#
    +# Bool#
    1#) State# d
    s'

    -- | Write a Word to @/addr/@ in base-256 big-endian representation and
    -- return the number of bytes written.
    wordToAddrBE# :: Word# -> Addr# -> State# s -> (# State# s, Word# #)
    wordToAddrBE# :: forall s. Word# -> Addr# -> State# s -> (# State# s, Word# #)
    wordToAddrBE# Word#
    w Addr#
    addr = Bool# -> Bool# -> State# s -> (# State# s, Word# #)
    forall {d}. Bool# -> Bool# -> State# d -> (# State# d, Word# #)
    go Bool#
    0# (WORD_SIZE_IN_BITS# -# clz)
       where
         !clz :: Bool#
    clz = Word# -> Bool#
    word2Int# (Word# -> Word#
    clz# Word#
    w Word# -> Word# -> Word#
    `and#` (Word# -> Word#
    not# Word#
    0b0111##)) -- keep complete bytes

         go :: Bool# -> Bool# -> State# d -> (# State# d, Word# #)
    go Bool#
    c Bool#
    sh State# d
    s
          | Bool#
    0# <- Bool#
    sh
          = (# State# d
    s, Bool# -> Word#
    int2Word# Bool#
    c #)

          | Bool
    True
          , Word8#
    w' <- Word# -> Word8#
    wordToWord8# (Word#
    w Word# -> Bool# -> Word#
    `uncheckedShiftRL#` (Bool#
    sh Bool# -> Bool# -> Bool#
    -# Bool#
    8#))
          = case Addr# -> Bool# -> Word8# -> State# d -> State# d
    forall d. Addr# -> Bool# -> Word8# -> State# d -> State# d
    writeWord8OffAddr# Addr#
    addr Bool#
    c Word8#
    w' State# d
    s of
             State# d
    s' -> Bool# -> Bool# -> State# d -> (# State# d, Word# #)
    go (Bool#
    c Bool# -> Bool# -> Bool#
    +# Bool#
    1#) (Bool#
    sh Bool# -> Bool# -> Bool#
    -# Bool#
    8#) State# d
    s'

    -- | Write a Word to @/addr/@ in base-256 representation and
    -- return the number of bytes written.
    --
    -- The endianness is selected with the Bool# parameter: write most significant
    -- byte first (big-endian) if @1#@ or least significant byte first
    -- (little-endian) if @0#@.
    wordToAddr# :: Word# -> Addr# -> Bool# -> State# s -> (# State# s, Word# #)
    wordToAddr# :: forall s.
    Word# -> Addr# -> Bool# -> State# s -> (# State# s, Word# #)
    wordToAddr# Word#
    a Addr#
    addr Bool#
    0# State# s
    s = Word# -> Addr# -> State# s -> (# State# s, Word# #)
    forall s. Word# -> Addr# -> State# s -> (# State# s, Word# #)
    wordToAddrLE# Word#
    a Addr#
    addr State# s
    s
    wordToAddr# Word#
    a Addr#
    addr Bool#
    _  State# s
    s = Word# -> Addr# -> State# s -> (# State# s, Word# #)
    forall s. Word# -> Addr# -> State# s -> (# State# s, Word# #)
    wordToAddrBE# Word#
    a Addr#
    addr State# s
    s

    -- | Read a Word from @/addr/@ in base-256 little-endian representation.
    --
    -- @'n' is the number of bytes to read.
    wordFromAddrLE# :: Word# -> Addr# -> State# s -> (# State# s, Word# #)
    wordFromAddrLE# :: forall s. Word# -> Addr# -> State# s -> (# State# s, Word# #)
    wordFromAddrLE# Word#
    n Addr#
    addr State# s
    s
       -- Optimize when we read a full word
       | WORD_SIZE_IN_BYTES## <- n
       = case Addr# -> Bool# -> State# s -> (# State# s, Word# #)
    forall d. Addr# -> Bool# -> State# d -> (# State# d, Word# #)
    readWordOffAddr# Addr#
    addr Bool#
    0# State# s
    s of
    #if defined(WORDS_BIGENDIAN)
          (# s', w #) -> (# s', wordReverseBytes# w #)
    #else
          (# State# s
    s', Word#
    w #) -> (# State# s
    s', Word#
    w #)
    #endif

    wordFromAddrLE# Word#
    n Addr#
    addr State# s
    s0 = Word# -> Bool# -> State# s -> (# State# s, Word# #)
    forall {d}. Word# -> Bool# -> State# d -> (# State# d, Word# #)
    go Word#
    0## Bool#
    0# State# s
    s0
       where
          go :: Word# -> Bool# -> State# d -> (# State# d, Word# #)
    go Word#
    w Bool#
    c State# d
    s
             | Bool# -> Bool
    isTrue# (Bool#
    c Bool# -> Bool# -> Bool#
    ==# Word# -> Bool#
    word2Int# Word#
    n)
             = (# State# d
    s, Word#
    w #)

             | Bool
    True
             = case Addr# -> Bool# -> State# d -> (# State# d, Word8# #)
    forall d. Addr# -> Bool# -> State# d -> (# State# d, Word8# #)
    readWord8OffAddr# Addr#
    addr Bool#
    c State# d
    s of
                (# State# d
    s', Word8#
    b #) -> Word# -> Bool# -> State# d -> (# State# d, Word# #)
    go (Word#
    w Word# -> Word# -> Word#
    `or#` (Word8# -> Word#
    word8ToWord# Word8#
    b Word# -> Bool# -> Word#
    `uncheckedShiftL#` (Bool#
    c Bool# -> Bool# -> Bool#
    `uncheckedIShiftL#` Bool#
    3#)))
                                  (Bool#
    c Bool# -> Bool# -> Bool#
    +# Bool#
    1#)
                                  State# d
    s'

    -- | Read a Word from @/addr/@ in base-256 big-endian representation.
    --
    -- @'n' is the number of bytes to read.
    wordFromAddrBE# :: Word# -> Addr# -> State# s -> (# State# s, Word# #)
    wordFromAddrBE# :: forall s. Word# -> Addr# -> State# s -> (# State# s, Word# #)
    wordFromAddrBE# Word#
    n Addr#
    addr State# s
    s
       -- Optimize when we read a full word
       | WORD_SIZE_IN_BYTES## <- n
       = case Addr# -> Bool# -> State# s -> (# State# s, Word# #)
    forall d. Addr# -> Bool# -> State# d -> (# State# d, Word# #)
    readWordOffAddr# Addr#
    addr Bool#
    0# State# s
    s of
    #if defined(WORDS_BIGENDIAN)
          (# s', w #) -> (# s', w #)
    #else
          (# State# s
    s', Word#
    w #) -> (# State# s
    s', Word# -> Word#
    wordReverseBytes# Word#
    w #)
    #endif

    wordFromAddrBE# Word#
    n Addr#
    addr State# s
    s0 = Word# -> Bool# -> State# s -> (# State# s, Word# #)
    forall {d}. Word# -> Bool# -> State# d -> (# State# d, Word# #)
    go Word#
    0## Bool#
    0# State# s
    s0
       where
          go :: Word# -> Bool# -> State# d -> (# State# d, Word# #)
    go Word#
    w Bool#
    c State# d
    s
             | Bool# -> Bool
    isTrue# (Bool#
    c Bool# -> Bool# -> Bool#
    ==# Word# -> Bool#
    word2Int# Word#
    n)
             = (# State# d
    s, Word#
    w #)

             | Bool
    True
             = case Addr# -> Bool# -> State# d -> (# State# d, Word8# #)
    forall d. Addr# -> Bool# -> State# d -> (# State# d, Word8# #)
    readWord8OffAddr# Addr#
    addr Bool#
    c State# d
    s of
                (# State# d
    s', Word8#
    b #) -> Word# -> Bool# -> State# d -> (# State# d, Word# #)
    go ((Word#
    w Word# -> Bool# -> Word#
    `uncheckedShiftL#` Bool#
    8#) Word# -> Word# -> Word#
    `or#` Word8# -> Word#
    word8ToWord# Word8#
    b)
                                  (Bool#
    c Bool# -> Bool# -> Bool#
    +# Bool#
    1#)
                                  State# d
    s'

    -- | Read a Word from @/addr/@ in base-256 representation.
    --
    -- @'n' is the number of bytes to read.
    --
    -- The endianness is selected with the Bool# parameter: write most significant
    -- byte first (big-endian) if @1#@ or least significant byte first
    -- (little-endian) if @0#@.
    wordFromAddr# :: Word# -> Addr# -> Bool# -> State# s -> (# State# s, Word# #)
    wordFromAddr# :: forall s.
    Word# -> Addr# -> Bool# -> State# s -> (# State# s, Word# #)
    wordFromAddr# Word#
    a Addr#
    addr Bool#
    0# State# s
    s = Word# -> Addr# -> State# s -> (# State# s, Word# #)
    forall s. Word# -> Addr# -> State# s -> (# State# s, Word# #)
    wordFromAddrLE# Word#
    a Addr#
    addr State# s
    s
    wordFromAddr# Word#
    a Addr#
    addr Bool#
    _  State# s
    s = Word# -> Addr# -> State# s -> (# State# s, Word# #)
    forall s. Word# -> Addr# -> State# s -> (# State# s, Word# #)
    wordFromAddrBE# Word#
    a Addr#
    addr State# s
    s

    -- | Write a full word with little-endian encoding
    wordWriteAddrLE# :: Word# -> Addr# -> State# s -> State# s
    wordWriteAddrLE# :: forall s. Word# -> Addr# -> State# s -> State# s
    wordWriteAddrLE# Word#
    w Addr#
    addr = Addr# -> Bool# -> Word# -> State# s -> State# s
    forall d. Addr# -> Bool# -> Word# -> State# d -> State# d
    writeWordOffAddr# Addr#
    addr Bool#
    0#
    #if defined(WORDS_BIGENDIAN)
       (wordReverseBytes# w)
    #else
       Word#
    w
    #endif

    -- | Write a full word with little-endian encoding
    wordWriteAddrBE# :: Word# -> Addr# -> State# s -> State# s
    wordWriteAddrBE# :: forall s. Word# -> Addr# -> State# s -> State# s
    wordWriteAddrBE# Word#
    w Addr#
    addr = Addr# -> Bool# -> Word# -> State# s -> State# s
    forall d. Addr# -> Bool# -> Word# -> State# d -> State# d
    writeWordOffAddr# Addr#
    addr Bool#
    0#
    #if defined(WORDS_BIGENDIAN)
       w
    #else
       (Word# -> Word#
    wordReverseBytes# Word#
    w)
    #endif

    -- | Write a Word to @/MutableByteArray/@ in base-256 little-endian
    -- representation and return the number of bytes written.
    --
    -- The offset is in bytes.
    wordToMutableByteArrayLE# :: Word# -> MutableByteArray# s -> Word# -> State# s -> (# State# s, Word# #)
    wordToMutableByteArrayLE# :: forall s.
    Word#
    -> MutableByteArray# s
    -> Word#
    -> State# s
    -> (# State# s, Word# #)
    wordToMutableByteArrayLE# Word#
    x MutableByteArray# s
    mba Word#
    off = Word# -> Bool# -> State# s -> (# State# s, Word# #)
    go Word#
    x Bool#
    0#
       where
          go :: Word# -> Bool# -> State# s -> (# State# s, Word# #)
    go Word#
    w Bool#
    c State# s
    s
             | Word#
    0## <- Word#
    w
             = (# State# s
    s, Bool# -> Word#
    int2Word# Bool#
    c #)

             | Bool
    True
             = case MutableByteArray# s -> Bool# -> Word8# -> State# s -> State# s
    forall d.
    MutableByteArray# d -> Bool# -> Word8# -> State# d -> State# d
    writeWord8Array# MutableByteArray# s
    mba (Word# -> Bool#
    word2Int# Word#
    off Bool# -> Bool# -> Bool#
    +# Bool#
    c) (Word# -> Word8#
    wordToWord8# Word#
    w) State# s
    s of
                State# s
    s' -> Word# -> Bool# -> State# s -> (# State# s, Word# #)
    go (Word#
    w Word# -> Bool# -> Word#
    `uncheckedShiftRL#` Bool#
    8#) (Bool#
    c Bool# -> Bool# -> Bool#
    +# Bool#
    1#) State# s
    s'

    -- | Write a Word to @/MutableByteArray/@ in base-256 big-endian representation and
    -- return the number of bytes written.
    --
    -- The offset is in bytes.
    wordToMutableByteArrayBE# :: Word# -> MutableByteArray# s -> Word# -> State# s -> (# State# s, Word# #)
    wordToMutableByteArrayBE# :: forall s.
    Word#
    -> MutableByteArray# s
    -> Word#
    -> State# s
    -> (# State# s, Word# #)
    wordToMutableByteArrayBE# Word#
    w MutableByteArray# s
    mba Word#
    off = Bool# -> Bool# -> State# s -> (# State# s, Word# #)
    go Bool#
    0# (WORD_SIZE_IN_BITS# -# clz)
       where
         !clz :: Bool#
    clz = Word# -> Bool#
    word2Int# (Word# -> Word#
    clz# Word#
    w Word# -> Word# -> Word#
    `and#` (Word# -> Word#
    not# Word#
    0b0111##)) -- keep complete bytes

         go :: Bool# -> Bool# -> State# s -> (# State# s, Word# #)
    go Bool#
    c Bool#
    sh State# s
    s
          | Bool#
    0# <- Bool#
    sh
          = (# State# s
    s, Bool# -> Word#
    int2Word# Bool#
    c #)

          | Bool
    True
          , Word8#
    w' <- Word# -> Word8#
    wordToWord8# (Word#
    w Word# -> Bool# -> Word#
    `uncheckedShiftRL#` (Bool#
    sh Bool# -> Bool# -> Bool#
    -# Bool#
    8#))
          = case MutableByteArray# s -> Bool# -> Word8# -> State# s -> State# s
    forall d.
    MutableByteArray# d -> Bool# -> Word8# -> State# d -> State# d
    writeWord8Array# MutableByteArray# s
    mba (Word# -> Bool#
    word2Int# Word#
    off Bool# -> Bool# -> Bool#
    +# Bool#
    c) Word8#
    w' State# s
    s of
             State# s
    s' -> Bool# -> Bool# -> State# s -> (# State# s, Word# #)
    go (Bool#
    c Bool# -> Bool# -> Bool#
    +# Bool#
    1#) (Bool#
    sh Bool# -> Bool# -> Bool#
    -# Bool#
    8#) State# s
    s'

    -- | Write a Word to @/MutableByteArray/@ in base-256 representation and
    -- return the number of bytes written.
    --
    -- The endianness is selected with the Bool# parameter: write most significant
    -- byte first (big-endian) if @1#@ or least significant byte first
    -- (little-endian) if @0#@.
    --
    -- The offset is in bytes.
    wordToMutableByteArray# :: Word# -> MutableByteArray# s -> Word# -> Bool# -> State# s -> (# State# s, Word# #)
    wordToMutableByteArray# :: forall s.
    Word#
    -> MutableByteArray# s
    -> Word#
    -> Bool#
    -> State# s
    -> (# State# s, Word# #)
    wordToMutableByteArray# Word#
    a MutableByteArray# s
    mba Word#
    off Bool#
    0# State# s
    s = Word#
    -> MutableByteArray# s
    -> Word#
    -> State# s
    -> (# State# s, Word# #)
    forall s.
    Word#
    -> MutableByteArray# s
    -> Word#
    -> State# s
    -> (# State# s, Word# #)
    wordToMutableByteArrayLE# Word#
    a MutableByteArray# s
    mba Word#
    off State# s
    s
    wordToMutableByteArray# Word#
    a MutableByteArray# s
    mba Word#
    off Bool#
    _  State# s
    s = Word#
    -> MutableByteArray# s
    -> Word#
    -> State# s
    -> (# State# s, Word# #)
    forall s.
    Word#
    -> MutableByteArray# s
    -> Word#
    -> State# s
    -> (# State# s, Word# #)
    wordToMutableByteArrayBE# Word#
    a MutableByteArray# s
    mba Word#
    off State# s
    s

    -- | Write a full word with little-endian encoding
    wordWriteMutableByteArrayLE# :: Word# -> MutableByteArray# s -> Word# -> State# s -> State# s
    wordWriteMutableByteArrayLE# :: forall s.
    Word# -> MutableByteArray# s -> Word# -> State# s -> State# s
    wordWriteMutableByteArrayLE# Word#
    w MutableByteArray# s
    mba Word#
    off = MutableByteArray# s -> Bool# -> Word# -> State# s -> State# s
    forall d.
    MutableByteArray# d -> Bool# -> Word# -> State# d -> State# d
    writeWord8ArrayAsWord# MutableByteArray# s
    mba (Word# -> Bool#
    word2Int# Word#
    off)
    #if defined(WORDS_BIGENDIAN)
       (wordReverseBytes# w)
    #else
       Word#
    w
    #endif

    -- | Write a full word with little-endian encoding
    wordWriteMutableByteArrayBE# :: Word# -> MutableByteArray# s -> Word# -> State# s -> State# s
    wordWriteMutableByteArrayBE# :: forall s.
    Word# -> MutableByteArray# s -> Word# -> State# s -> State# s
    wordWriteMutableByteArrayBE# Word#
    w MutableByteArray# s
    mba Word#
    off = MutableByteArray# s -> Bool# -> Word# -> State# s -> State# s
    forall d.
    MutableByteArray# d -> Bool# -> Word# -> State# d -> State# d
    writeWord8ArrayAsWord# MutableByteArray# s
    mba (Word# -> Bool#
    word2Int# Word#
    off)
    #if defined(WORDS_BIGENDIAN)
       w
    #else
       (Word# -> Word#
    wordReverseBytes# Word#
    w)
    #endif

    -- | Read a Word from @/ByteArray/@ in base-256 little-endian representation.
    --
    -- @'n' is the number of bytes to read.
    wordFromByteArrayLE# :: Word# -> ByteArray# -> Word# -> Word#
    wordFromByteArrayLE# :: Word# -> ByteArray# -> Word# -> Word#
    wordFromByteArrayLE# Word#
    n ByteArray#
    ba Word#
    off =
       case Word#
    n of
          -- Optimize when we read a full word
          WORD_SIZE_IN_BYTES## -> case indexWord8ArrayAsWord# ba (word2Int# off) of
    #if defined(WORDS_BIGENDIAN)
             w -> wordReverseBytes# w
    #else
             w -> w
    #endif

          Word#
    _ -> let
                go :: Word# -> Bool# -> Word#
    go Word#
    w Bool#
    c
                   | Bool# -> Bool
    isTrue# (Bool#
    c Bool# -> Bool# -> Bool#
    ==# Word# -> Bool#
    word2Int# Word#
    n)
                   = Word#
    w

                   | Bool
    True
                   = case ByteArray# -> Bool# -> Word8#
    indexWord8Array# ByteArray#
    ba (Word# -> Bool#
    word2Int# Word#
    off Bool# -> Bool# -> Bool#
    +# Bool#
    c) of
                      Word8#
    b -> Word# -> Bool# -> Word#
    go (Word#
    w Word# -> Word# -> Word#
    `or#` (Word8# -> Word#
    word8ToWord# Word8#
    b Word# -> Bool# -> Word#
    `uncheckedShiftL#` (Bool#
    c Bool# -> Bool# -> Bool#
    `uncheckedIShiftL#` Bool#
    3#)))
                              (Bool#
    c Bool# -> Bool# -> Bool#
    +# Bool#
    1#)
               in Word# -> Bool# -> Word#
    go Word#
    0## Bool#
    0#

    -- | Read a Word from @/ByteArray/@ in base-256 big-endian representation.
    --
    -- @'n' is the number of bytes to read.
    wordFromByteArrayBE# :: Word# -> ByteArray# -> Word# -> Word#
    wordFromByteArrayBE# :: Word# -> ByteArray# -> Word# -> Word#
    wordFromByteArrayBE# Word#
    n ByteArray#
    ba Word#
    off
       -- Optimize when we read a full word
       | WORD_SIZE_IN_BYTES## <- n
       = case ByteArray# -> Bool# -> Word#
    indexWord8ArrayAsWord# ByteArray#
    ba (Word# -> Bool#
    word2Int# Word#
    off) of
    #if defined(WORDS_BIGENDIAN)
          w -> w
    #else
          Word#
    w -> Word# -> Word#
    wordReverseBytes# Word#
    w
    #endif

    wordFromByteArrayBE# Word#
    n ByteArray#
    ba Word#
    off = Word# -> Bool# -> Word#
    go Word#
    0## Bool#
    0#
       where
          go :: Word# -> Bool# -> Word#
    go Word#
    w Bool#
    c
             | Bool# -> Bool
    isTrue# (Bool#
    c Bool# -> Bool# -> Bool#
    ==# Word# -> Bool#
    word2Int# Word#
    n)
             = Word#
    w

             | Bool
    True
             = case ByteArray# -> Bool# -> Word8#
    indexWord8Array# ByteArray#
    ba (Word# -> Bool#
    word2Int# Word#
    off Bool# -> Bool# -> Bool#
    +# Bool#
    c) of
                Word8#
    b -> Word# -> Bool# -> Word#
    go ((Word#
    w Word# -> Bool# -> Word#
    `uncheckedShiftL#` Bool#
    8#) Word# -> Word# -> Word#
    `or#` Word8# -> Word#
    word8ToWord# Word8#
    b) (Bool#
    c Bool# -> Bool# -> Bool#
    +# Bool#
    1#)

    -- | Read a Word from @/ByteArray/@ in base-256 representation.
    --
    -- @'n' is the number of bytes to read.
    --
    -- The endianness is selected with the Bool# parameter: write most significant
    -- byte first (big-endian) if @1#@ or least significant byte first
    -- (little-endian) if @0#@.
    wordFromByteArray# :: Word# -> ByteArray# -> Word# -> Bool# -> Word#
    wordFromByteArray# :: Word# -> ByteArray# -> Word# -> Bool# -> Word#
    wordFromByteArray# Word#
    a ByteArray#
    ba Word#
    off Bool#
    0# = Word# -> ByteArray# -> Word# -> Word#
    wordFromByteArrayLE# Word#
    a ByteArray#
    ba Word#
    off
    wordFromByteArray# Word#
    a ByteArray#
    ba Word#
    off Bool#
    _  = Word# -> ByteArray# -> Word# -> Word#
    wordFromByteArrayBE# Word#
    a ByteArray#
    ba Word#
    off

    ----------------------------------
    -- IO
    ----------------------------------

    ioVoid :: IO a -> State# RealWorld -> State# RealWorld
    ioVoid :: forall a. IO a -> State# RealWorld -> State# RealWorld
    ioVoid (IO State# RealWorld -> (# State# RealWorld, a #)
    io) State# RealWorld
    s = case State# RealWorld -> (# State# RealWorld, a #)
    io State# RealWorld
    s of
                      (# State# RealWorld
    s', a
    _ #) -> State# RealWorld
    s'

    ioWord# :: IO Word -> State# RealWorld -> (# State# RealWorld, Word# #)
    ioWord# :: IO Word -> State# RealWorld -> (# State# RealWorld, Word# #)
    ioWord# (IO State# RealWorld -> (# State# RealWorld, Word #)
    io) State# RealWorld
    s = case State# RealWorld -> (# State# RealWorld, Word #)
    io State# RealWorld
    s of
       (# State# RealWorld
    s', W# Word#
    w #) -> (# State# RealWorld
    s', Word#
    w #)

    ioInt# :: IO Int -> State# RealWorld -> (# State# RealWorld, Int# #)
    ioInt# :: IO Int -> State# RealWorld -> (# State# RealWorld, Bool# #)
    ioInt# (IO State# RealWorld -> (# State# RealWorld, Int #)
    io) State# RealWorld
    s = case State# RealWorld -> (# State# RealWorld, Int #)
    io State# RealWorld
    s of
       (# State# RealWorld
    s', I# Bool#
    i #) -> (# State# RealWorld
    s', Bool#
    i #)

    ioBool :: IO Bool -> State# RealWorld -> (# State# RealWorld, Bool# #)
    ioBool :: IO Bool -> State# RealWorld -> (# State# RealWorld, Bool# #)
    ioBool (IO State# RealWorld -> (# State# RealWorld, Bool #)
    io) State# RealWorld
    s = case State# RealWorld -> (# State# RealWorld, Bool #)
    io State# RealWorld
    s of
       (# State# RealWorld
    s', Bool
    False #) -> (# State# RealWorld
    s', Bool#
    0# #)
       (# State# RealWorld
    s', Bool
    True #) -> (# State# RealWorld
    s', Bool#
    1# #)

    ----------------------------------
    -- Exception
    ----------------------------------

    -- Note [ghc-bignum exceptions]
    -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    -- `ghc-bignum` package can't depend on `base` package (it would create a cyclic
    -- dependency). Hence it can't import "Control.Exception" and throw exceptions
    -- the usual way. Instead it uses some wired-in functions from `ghc-prim` which
    -- themselves call wired-in functions from the RTS: raiseOverflow,
    -- raiseUnderflow, raiseDivZero.
    --
    -- We have to be careful when we want to throw an exception instead of returning
    -- an unlifted value (e.g. Word#, unboxed tuple, etc.). We have to ensure the
    -- evaluation of the exception throwing function before returning a dummy value,
    -- otherwise it will be removed by the simplifier as dead-code.
    --
    --    foo :: ... -> Word#
    --    foo = ... case raiseDivZero of
    --                !_ -> 0## -- the bang-pattern is necessary!
    --                          -- 0## is a dummy value (unreachable code)
    --

    unexpectedValue_Int# :: (# #) -> Int#
    unexpectedValue_Int# :: (# #) -> Bool#
    unexpectedValue_Int# (# #)
    _ = case Any
    forall a. a
    unexpectedValue of
       !Any
    _ -> Bool#
    0# -- see Note [ghc-bignum exceptions]

    unexpectedValue_Word# :: (# #) -> Word#
    unexpectedValue_Word# :: (# #) -> Word#
    unexpectedValue_Word# (# #)
    _ = case Any
    forall a. a
    unexpectedValue of
       !Any
    _ -> Word#
    0## -- see Note [ghc-bignum exceptions]

    raiseDivZero_Word# :: (# #) -> Word#
    raiseDivZero_Word# :: (# #) -> Word#
    raiseDivZero_Word# (# #)
    _ = case Any
    forall a. a
    raiseDivZero of
       !Any
    _ -> Word#
    0## -- see Note [ghc-bignum exceptions]

    raiseUnderflow_Word# :: (# #) -> Word#
    raiseUnderflow_Word# :: (# #) -> Word#
    raiseUnderflow_Word# (# #)
    _ = case Any
    forall a. a
    raiseUnderflow of
       !Any
    _ -> Word#
    0## -- see Note [ghc-bignum exceptions]

    #if (__GLASGOW_HASKELL__ >= 811)

    unexpectedValue :: a
    unexpectedValue :: forall a. a
    unexpectedValue = a
    forall a. a
    raiseOverflow

    #else

    -- Before GHC 8.11 we use the exception trick taken from #14664
    exception :: a
    {-# NOINLINE exception #-}
    exception = runRW# \s ->
       case atomicLoop s of
          (# _, a #) -> a
       where
          atomicLoop s = atomically# atomicLoop s

    raiseUnderflow :: a
    raiseUnderflow = exception

    raiseDivZero :: a
    raiseDivZero = exception

    unexpectedValue :: a
    unexpectedValue = exception

    #endif