{-# LANGUAGE CPP #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE KindSignatures #-}
{-# OPTIONS_GHC -Wno-name-shadowing #-}

module GHC.Internal.Bignum.WordArray where

import GHC.Prim
import GHC.Magic
import GHC.Types
import GHC.Internal.Bignum.Primitives

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

default ()

-- | Unlifted array of Word
type WordArray#        = ByteArray#
type MutableWordArray# = MutableByteArray#

data WordArray          = WordArray WordArray#
data MutableWordArray s = MutableWordArray (MutableWordArray# s)

-- | Convert limb count into byte count
wordsToBytes# :: Int# -> Int#
wordsToBytes# :: Int# -> Int#
wordsToBytes# Int#
i = Int#
i Int# -> Int# -> Int#
`uncheckedIShiftL#` WORD_SIZE_BYTES_SHIFT#

-- | Convert byte count into limb count
bytesToWords# :: Int# -> Int#
bytesToWords# :: Int# -> Int#
bytesToWords# Int#
i = Int#
i Int# -> Int# -> Int#
`uncheckedIShiftRL#` WORD_SIZE_BYTES_SHIFT#


-- | Create a new WordArray# of the given size (*in Word#*) and apply the
-- action to it before returning it frozen
withNewWordArray#
   :: Int#  -- ^ Size in Word
   -> (MutableWordArray# RealWorld -> State# RealWorld -> State# RealWorld)
   -> WordArray#
withNewWordArray# :: Int#
-> (MutableWordArray# RealWorld
    -> State# RealWorld -> State# RealWorld)
-> WordArray#
withNewWordArray# Int#
sz MutableWordArray# RealWorld -> State# RealWorld -> State# RealWorld
act = case (State# RealWorld -> (# State# RealWorld, WordArray# #))
-> (# State# RealWorld, WordArray# #)
forall o. (State# RealWorld -> o) -> o
runRW# State# RealWorld -> (# State# RealWorld, WordArray# #)
io of (# State# RealWorld
_, WordArray#
a #) -> WordArray#
a
   where
      io :: State# RealWorld -> (# State# RealWorld, WordArray# #)
io State# RealWorld
s =
         case Int#
-> State# RealWorld
-> (# State# RealWorld, MutableWordArray# RealWorld #)
forall s. Int# -> State# s -> (# State# s, MutableWordArray# s #)
newWordArray# Int#
sz State# RealWorld
s of { (# State# RealWorld
s, MutableWordArray# RealWorld
mwa #) ->
         case MutableWordArray# RealWorld -> State# RealWorld -> State# RealWorld
act MutableWordArray# RealWorld
mwa State# RealWorld
s          of { State# RealWorld
s ->
         MutableWordArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, WordArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, WordArray# #)
unsafeFreezeByteArray# MutableWordArray# RealWorld
mwa State# RealWorld
s
         }}

-- | Create two new WordArray# of the given sizes (*in Word#*) and apply the
-- action to them before returning them frozen
withNewWordArray2#
   :: Int# -- ^ Size in Word
   -> Int# -- ^ Ditto
   -> (MutableWordArray# RealWorld
      -> MutableWordArray# RealWorld
      -> State# RealWorld
      -> State# RealWorld)
   -> (# WordArray#, WordArray# #)
withNewWordArray2# :: Int#
-> Int#
-> (MutableWordArray# RealWorld
    -> MutableWordArray# RealWorld
    -> State# RealWorld
    -> State# RealWorld)
-> (# WordArray#, WordArray# #)
withNewWordArray2# Int#
sz1 Int#
sz2 MutableWordArray# RealWorld
-> MutableWordArray# RealWorld
-> State# RealWorld
-> State# RealWorld
act = case (State# RealWorld
 -> (# State# RealWorld, (# WordArray#, WordArray# #) #))
-> (# State# RealWorld, (# WordArray#, WordArray# #) #)
forall o. (State# RealWorld -> o) -> o
runRW# State# RealWorld
-> (# State# RealWorld, (# WordArray#, WordArray# #) #)
io of (# State# RealWorld
_, (# WordArray#, WordArray# #)
a #) -> (# WordArray#, WordArray# #)
a
   where
      io :: State# RealWorld
-> (# State# RealWorld, (# WordArray#, WordArray# #) #)
io State# RealWorld
s =
         case Int#
-> State# RealWorld
-> (# State# RealWorld, MutableWordArray# RealWorld #)
forall s. Int# -> State# s -> (# State# s, MutableWordArray# s #)
newWordArray# Int#
sz1 State# RealWorld
s of { (# State# RealWorld
s, MutableWordArray# RealWorld
mwa1 #) ->
         case Int#
-> State# RealWorld
-> (# State# RealWorld, MutableWordArray# RealWorld #)
forall s. Int# -> State# s -> (# State# s, MutableWordArray# s #)
newWordArray# Int#
sz2 State# RealWorld
s of { (# State# RealWorld
s, MutableWordArray# RealWorld
mwa2 #) ->
         case MutableWordArray# RealWorld
-> MutableWordArray# RealWorld
-> State# RealWorld
-> State# RealWorld
act MutableWordArray# RealWorld
mwa1 MutableWordArray# RealWorld
mwa2 State# RealWorld
s     of { State# RealWorld
s ->
         case MutableWordArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, WordArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, WordArray# #)
unsafeFreezeByteArray# MutableWordArray# RealWorld
mwa1 State# RealWorld
s of { (# State# RealWorld
s, WordArray#
wa1 #) ->
         case MutableWordArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, WordArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, WordArray# #)
unsafeFreezeByteArray# MutableWordArray# RealWorld
mwa2 State# RealWorld
s of { (# State# RealWorld
s, WordArray#
wa2 #) ->
            (# State# RealWorld
s, (# WordArray#
wa1, WordArray#
wa2 #) #)
         }}}}}

-- | Create a new WordArray#
newWordArray# :: Int# -> State# s -> (# State# s, MutableWordArray# s #)
newWordArray# :: forall s. Int# -> State# s -> (# State# s, MutableWordArray# s #)
newWordArray# Int#
sz State# s
s = Int# -> State# s -> (# State# s, MutableByteArray# s #)
forall s. Int# -> State# s -> (# State# s, MutableWordArray# s #)
newByteArray# (Int# -> Int#
wordsToBytes# Int#
sz) State# s
s

-- | Create a new WordArray# of the given size (*in Word#*), apply the action to
-- it, trim its most significant zeroes, then return it frozen
withNewWordArrayTrimmed#
   :: Int#  -- ^ Size in Word
   -> (MutableWordArray# RealWorld -> State# RealWorld -> State# RealWorld)
   -> WordArray#
withNewWordArrayTrimmed# :: Int#
-> (MutableWordArray# RealWorld
    -> State# RealWorld -> State# RealWorld)
-> WordArray#
withNewWordArrayTrimmed# Int#
sz MutableWordArray# RealWorld -> State# RealWorld -> State# RealWorld
act = Int#
-> (MutableWordArray# RealWorld
    -> State# RealWorld -> State# RealWorld)
-> WordArray#
withNewWordArray# Int#
sz \MutableWordArray# RealWorld
mwa State# RealWorld
s ->
   case MutableWordArray# RealWorld -> State# RealWorld -> State# RealWorld
act MutableWordArray# RealWorld
mwa State# RealWorld
s of
      State# RealWorld
s' -> MutableWordArray# RealWorld -> State# RealWorld -> State# RealWorld
forall s. MutableByteArray# s -> State# s -> State# s
mwaTrimZeroes# MutableWordArray# RealWorld
mwa State# RealWorld
s'

-- | Create two new WordArray# of the given sizes (*in Word#*), apply the action
-- to them, trim their most significant zeroes, then return them frozen
withNewWordArray2Trimmed#
   :: Int#  -- ^ Size in Word
   -> Int#  -- ^ Ditto
   -> (MutableWordArray# RealWorld
      -> MutableWordArray# RealWorld
      -> State# RealWorld
      -> State# RealWorld)
   -> (# WordArray#, WordArray# #)
withNewWordArray2Trimmed# :: Int#
-> Int#
-> (MutableWordArray# RealWorld
    -> MutableWordArray# RealWorld
    -> State# RealWorld
    -> State# RealWorld)
-> (# WordArray#, WordArray# #)
withNewWordArray2Trimmed# Int#
sz1 Int#
sz2 MutableWordArray# RealWorld
-> MutableWordArray# RealWorld
-> State# RealWorld
-> State# RealWorld
act = Int#
-> Int#
-> (MutableWordArray# RealWorld
    -> MutableWordArray# RealWorld
    -> State# RealWorld
    -> State# RealWorld)
-> (# WordArray#, WordArray# #)
withNewWordArray2# Int#
sz1 Int#
sz2 \MutableWordArray# RealWorld
mwa1 MutableWordArray# RealWorld
mwa2 State# RealWorld
s ->
   case MutableWordArray# RealWorld
-> MutableWordArray# RealWorld
-> State# RealWorld
-> State# RealWorld
act MutableWordArray# RealWorld
mwa1 MutableWordArray# RealWorld
mwa2 State# RealWorld
s of
      State# RealWorld
s' -> case MutableWordArray# RealWorld -> State# RealWorld -> State# RealWorld
forall s. MutableByteArray# s -> State# s -> State# s
mwaTrimZeroes# MutableWordArray# RealWorld
mwa1 State# RealWorld
s' of
         State# RealWorld
s'' -> MutableWordArray# RealWorld -> State# RealWorld -> State# RealWorld
forall s. MutableByteArray# s -> State# s -> State# s
mwaTrimZeroes# MutableWordArray# RealWorld
mwa2 State# RealWorld
s''

-- | Create a new WordArray# of the given size (*in Word#*), apply the action to
-- it. If the action returns true#, trim its most significant zeroes, then
-- return it frozen. Otherwise, return ().
withNewWordArrayTrimmedMaybe#
   :: Int#  -- ^ Size in Word
   -> (MutableWordArray# RealWorld -> State# RealWorld -> (# State# RealWorld, Bool# #))
   -> (# (# #) | WordArray# #)
withNewWordArrayTrimmedMaybe# :: Int#
-> (MutableWordArray# RealWorld
    -> State# RealWorld -> (# State# RealWorld, Int# #))
-> (# (# #) | WordArray# #)
withNewWordArrayTrimmedMaybe# Int#
sz MutableWordArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, Int# #)
act = case (State# RealWorld
 -> (# State# RealWorld, (# (# #) | WordArray# #) #))
-> (# State# RealWorld, (# (# #) | WordArray# #) #)
forall o. (State# RealWorld -> o) -> o
runRW# State# RealWorld
-> (# State# RealWorld, (# (# #) | WordArray# #) #)
io of (# State# RealWorld
_, (# (# #) | WordArray# #)
a #) -> (# (# #) | WordArray# #)
a
   where
      io :: State# RealWorld
-> (# State# RealWorld, (# (# #) | WordArray# #) #)
io State# RealWorld
s =
         case Int#
-> State# RealWorld
-> (# State# RealWorld, MutableWordArray# RealWorld #)
forall s. Int# -> State# s -> (# State# s, MutableWordArray# s #)
newWordArray# Int#
sz State# RealWorld
s of
            (# State# RealWorld
s, MutableWordArray# RealWorld
mwa #) -> case MutableWordArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, Int# #)
act MutableWordArray# RealWorld
mwa State# RealWorld
s of
               (# State# RealWorld
s, Int#
0# #) -> (# State# RealWorld
s, (# (# #) | #) #)
               (# State# RealWorld
s, Int#
_  #) -> case MutableWordArray# RealWorld -> State# RealWorld -> State# RealWorld
forall s. MutableByteArray# s -> State# s -> State# s
mwaTrimZeroes# MutableWordArray# RealWorld
mwa State# RealWorld
s of
                  State# RealWorld
s -> case MutableWordArray# RealWorld
-> State# RealWorld -> (# State# RealWorld, WordArray# #)
forall d.
MutableByteArray# d -> State# d -> (# State# d, WordArray# #)
unsafeFreezeByteArray# MutableWordArray# RealWorld
mwa State# RealWorld
s of
                     (# State# RealWorld
s, WordArray#
ba #) -> (# State# RealWorld
s, (# | WordArray#
ba #) #)

-- | Create a WordArray# from two Word#
--
-- `wordArrayFromWord2# h l
--    where h is the most significant word
--          l is the least significant word
wordArrayFromWord2# :: Word# -> Word# -> WordArray#
wordArrayFromWord2# :: Word# -> Word# -> WordArray#
wordArrayFromWord2# Word#
h Word#
l   =
   Int#
-> (MutableWordArray# RealWorld
    -> State# RealWorld -> State# RealWorld)
-> WordArray#
withNewWordArray# Int#
2# \MutableWordArray# RealWorld
mwa State# RealWorld
s ->
      case MutableWordArray# RealWorld
-> Int# -> Word# -> State# RealWorld -> State# RealWorld
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaWrite# MutableWordArray# RealWorld
mwa Int#
0# Word#
l State# RealWorld
s of
         State# RealWorld
s -> MutableWordArray# RealWorld
-> Int# -> Word# -> State# RealWorld -> State# RealWorld
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaWrite# MutableWordArray# RealWorld
mwa Int#
1# Word#
h State# RealWorld
s

-- | Create a WordArray# from one Word#
wordArrayFromWord# :: Word# -> WordArray#
wordArrayFromWord# :: Word# -> WordArray#
wordArrayFromWord# Word#
w   =
   Int#
-> (MutableWordArray# RealWorld
    -> State# RealWorld -> State# RealWorld)
-> WordArray#
withNewWordArray# Int#
1# \MutableWordArray# RealWorld
mwa State# RealWorld
s ->
      MutableWordArray# RealWorld
-> Int# -> Word# -> State# RealWorld -> State# RealWorld
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaWrite# MutableWordArray# RealWorld
mwa Int#
0# Word#
w State# RealWorld
s

-- | Word array size
wordArraySize# :: WordArray# -> Int#
wordArraySize# :: WordArray# -> Int#
wordArraySize# WordArray#
ba = Int# -> Int#
bytesToWords# (WordArray# -> Int#
sizeofByteArray# WordArray#
ba)


-- | Equality test for WordArray#

-- | Get size in Words
mwaSize# :: MutableWordArray# s-> State# s -> (# State# s, Int# #)
mwaSize# :: forall s. MutableWordArray# s -> State# s -> (# State# s, Int# #)
mwaSize# MutableWordArray# s
mba State# s
s = case MutableWordArray# s -> State# s -> (# State# s, Int# #)
forall s. MutableWordArray# s -> State# s -> (# State# s, Int# #)
getSizeofMutableByteArray# MutableWordArray# s
mba State# s
s of
   (# State# s
s2, Int#
sz #) -> (# State# s
s2, Int# -> Int#
bytesToWords# Int#
sz #)

-- | Get the last Word (must be non empty!)
wordArrayLast# :: WordArray# -> Word#
wordArrayLast# :: WordArray# -> Word#
wordArrayLast# WordArray#
a = WordArray# -> Int# -> Word#
indexWordArray# WordArray#
a (WordArray# -> Int#
wordArraySize# WordArray#
a Int# -> Int# -> Int#
-# Int#
1#)

-- | Copy Words from a WordArray
--
-- Don't do anything if the number of words to copy is <= 0
mwaArrayCopy# :: MutableByteArray# s -> Int# -> WordArray# -> Int# -> Int# -> State# s -> State# s
mwaArrayCopy# :: forall s.
MutableByteArray# s
-> Int# -> WordArray# -> Int# -> Int# -> State# s -> State# s
mwaArrayCopy# MutableByteArray# s
dst Int#
dstIdx WordArray#
src Int#
srcIdx Int#
n State# s
s
   | Int# -> Bool
isTrue# (Int#
n Int# -> Int# -> Int#
<=# Int#
0#) = State# s
s
   | Bool
True = WordArray#
-> Int#
-> MutableByteArray# s
-> Int#
-> Int#
-> State# s
-> State# s
forall d.
WordArray#
-> Int#
-> MutableByteArray# d
-> Int#
-> Int#
-> State# d
-> State# d
copyByteArray#
               WordArray#
src (Int# -> Int#
wordsToBytes# Int#
srcIdx)
               MutableByteArray# s
dst (Int# -> Int#
wordsToBytes# Int#
dstIdx)
               (Int# -> Int#
wordsToBytes# Int#
n) State# s
s

-- | Shrink last words of a WordArray
mwaShrink# :: MutableByteArray# s -> Int# -> State# s -> State# s
mwaShrink# :: forall s. MutableByteArray# s -> Int# -> State# s -> State# s
mwaShrink# MutableByteArray# s
_mwa Int#
0# State# s
s = State# s
s
mwaShrink# MutableByteArray# s
mwa  Int#
i  State# s
s =
   case MutableByteArray# s -> State# s -> (# State# s, Int# #)
forall s. MutableWordArray# s -> State# s -> (# State# s, Int# #)
mwaSize# MutableByteArray# s
mwa State# s
s of
      (# State# s
s, Int#
n #) -> MutableByteArray# s -> Int# -> State# s -> State# s
forall s. MutableByteArray# s -> Int# -> State# s -> State# s
shrinkMutableByteArray# MutableByteArray# s
mwa (Int# -> Int#
wordsToBytes# (Int#
n Int# -> Int# -> Int#
-# Int#
i)) State# s
s

-- | Set size
mwaSetSize# :: MutableByteArray# s -> Int# -> State# s -> State# s
mwaSetSize# :: forall s. MutableByteArray# s -> Int# -> State# s -> State# s
mwaSetSize# MutableByteArray# s
mwa Int#
n State# s
s = MutableByteArray# s -> Int# -> State# s -> State# s
forall s. MutableByteArray# s -> Int# -> State# s -> State# s
shrinkMutableByteArray# MutableByteArray# s
mwa (Int# -> Int#
wordsToBytes# Int#
n) State# s
s

-- | Copy the WordArray into the MWA and shrink the size of MWA to the one of
-- the WordArray
mwaInitCopyShrink# :: MutableByteArray# s -> WordArray# -> State# s -> State# s
mwaInitCopyShrink# :: forall s. MutableByteArray# s -> WordArray# -> State# s -> State# s
mwaInitCopyShrink# MutableByteArray# s
mwa WordArray#
wa State# s
s =
   case MutableByteArray# s
-> Int# -> WordArray# -> Int# -> Int# -> State# s -> State# s
forall s.
MutableByteArray# s
-> Int# -> WordArray# -> Int# -> Int# -> State# s -> State# s
mwaArrayCopy# MutableByteArray# s
mwa Int#
0# WordArray#
wa Int#
0# (WordArray# -> Int#
wordArraySize# WordArray#
wa) State# s
s of
      State# s
s -> MutableByteArray# s -> Int# -> State# s -> State# s
forall s. MutableByteArray# s -> Int# -> State# s -> State# s
mwaSetSize# MutableByteArray# s
mwa (WordArray# -> Int#
wordArraySize# WordArray#
wa) State# s
s

-- | Trim ending zeroes
mwaTrimZeroes# :: MutableByteArray# s -> State# s -> State# s
mwaTrimZeroes# :: forall s. MutableByteArray# s -> State# s -> State# s
mwaTrimZeroes# MutableByteArray# s
mwa State# s
s1 =
   case MutableByteArray# s -> State# s -> (# State# s, Int# #)
forall s. MutableWordArray# s -> State# s -> (# State# s, Int# #)
mwaClz MutableByteArray# s
mwa State# s
s1 of
      (# State# s
s2, Int#
0# #) -> State# s
s2
      (# State# s
s2, Int#
c  #) -> MutableByteArray# s -> Int# -> State# s -> State# s
forall s. MutableByteArray# s -> Int# -> State# s -> State# s
mwaShrink# MutableByteArray# s
mwa Int#
c State# s
s2

-- | Count leading zero Words
mwaClz :: MutableWordArray# s -> State# s -> (# State# s, Int# #)
mwaClz :: forall s. MutableWordArray# s -> State# s -> (# State# s, Int# #)
mwaClz MutableWordArray# s
mwa State# s
s1 = case MutableWordArray# s -> State# s -> (# State# s, Int# #)
forall s. MutableWordArray# s -> State# s -> (# State# s, Int# #)
mwaSize# MutableWordArray# s
mwa State# s
s1 of
   (# State# s
s2,Int#
sz #)  -> MutableWordArray# s -> Int# -> State# s -> (# State# s, Int# #)
forall s.
MutableWordArray# s -> Int# -> State# s -> (# State# s, Int# #)
mwaClzAt MutableWordArray# s
mwa (Int#
sz Int# -> Int# -> Int#
-# Int#
1#) State# s
s2

-- | Count leading zero Words starting at given position
mwaClzAt :: MutableWordArray# s -> Int# -> State# s -> (# State# s, Int# #)
mwaClzAt :: forall s.
MutableWordArray# s -> Int# -> State# s -> (# State# s, Int# #)
mwaClzAt MutableWordArray# s
mwa = Int# -> Int# -> State# s -> (# State# s, Int# #)
go Int#
0#
   where
      go :: Int# -> Int# -> State# s -> (# State# s, Int# #)
go Int#
c Int#
i State# s
s
         | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
<# Int#
0#) = (# State# s
s, Int#
c #)
         | Bool
True = case MutableWordArray# s -> Int# -> State# s -> (# State# s, Word# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
readWordArray# MutableWordArray# s
mwa Int#
i State# s
s of
            (# State# s
s', Word#
0## #) -> Int# -> Int# -> State# s -> (# State# s, Int# #)
go (Int#
c Int# -> Int# -> Int#
+# Int#
1#) (Int#
i Int# -> Int# -> Int#
-# Int#
1#) State# s
s'
            (# State# s
s', Word#
_   #) -> (# State# s
s', Int#
c #)

-- | Count leading zero Words starting at given position
waClzAt :: WordArray# -> Int# -> Int#
waClzAt :: WordArray# -> Int# -> Int#
waClzAt WordArray#
wa = Int# -> Int# -> Int#
go Int#
0#
   where
      go :: Int# -> Int# -> Int#
go Int#
c Int#
i
         | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
<# Int#
0#)
         = Int#
c

         | Word#
0## <- WordArray# -> Int# -> Word#
indexWordArray# WordArray#
wa Int#
i
         = Int# -> Int# -> Int#
go (Int#
c Int# -> Int# -> Int#
+# Int#
1#) (Int#
i Int# -> Int# -> Int#
-# Int#
1#)

         | Bool
True
         = Int#
c

-- | Compare the most signiciant limbs of a and b. The comparison stops (i.e.
-- returns EQ) when there isn't enough lims in a or b to perform another
-- comparison.
wordArrayCompareMSWords :: WordArray# -> WordArray# -> Ordering
wordArrayCompareMSWords :: WordArray# -> WordArray# -> Ordering
wordArrayCompareMSWords WordArray#
wa WordArray#
wb
   | Int#
0# <- Int#
szA
   , Int#
0# <- Int#
szB
   = Ordering
EQ

   | Int#
0# <- Int#
szA
   = Ordering
LT

   | Int#
0# <- Int#
szB
   = Ordering
GT

   | Bool
True
   = Int# -> Int# -> Ordering
go (Int#
szA Int# -> Int# -> Int#
-# Int#
1#) (Int#
szB Int# -> Int# -> Int#
-# Int#
1#)
   where
      szA :: Int#
szA  = WordArray# -> Int#
wordArraySize# WordArray#
wa
      szB :: Int#
szB  = WordArray# -> Int#
wordArraySize# WordArray#
wb

      go :: Int# -> Int# -> Ordering
go Int#
i Int#
j
         | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
<# Int#
0#) = Ordering
EQ
         | Int# -> Bool
isTrue# (Int#
j Int# -> Int# -> Int#
<# Int#
0#) = Ordering
EQ
         | Bool
True =
            let
               a :: Word#
a = WordArray# -> Int# -> Word#
indexWordArray# WordArray#
wa Int#
i
               b :: Word#
b = WordArray# -> Int# -> Word#
indexWordArray# WordArray#
wb Int#
j
            in if | Int# -> Bool
isTrue# (Word#
a Word# -> Word# -> Int#
`gtWord#` Word#
b) -> Ordering
GT
                  | Int# -> Bool
isTrue# (Word#
b Word# -> Word# -> Int#
`gtWord#` Word#
a) -> Ordering
LT
                  | Bool
True                    -> Int# -> Int# -> Ordering
go (Int#
i Int# -> Int# -> Int#
-# Int#
1#) (Int#
j Int# -> Int# -> Int#
-# Int#
1#)


-- | Compute MutableWordArray <- WordArray + Word
--
-- The MutableWordArray may not be initialized and will be erased anyway.
--
-- Input: Size(MutableWordArray) = Size(WordArray) + 1
-- Output: Size(MutableWordArray) = Size(WordArray) [+ 1]
mwaInitArrayPlusWord :: MutableWordArray# s -> WordArray# -> Word# -> State# s -> State#s
mwaInitArrayPlusWord :: forall s.
MutableWordArray# s -> WordArray# -> Word# -> State# s -> State# s
mwaInitArrayPlusWord MutableWordArray# s
mwa WordArray#
wa = Int# -> Word# -> State# s -> State# s
go Int#
0#
   where
      sz :: Int#
sz = WordArray# -> Int#
wordArraySize# WordArray#
wa
      go :: Int# -> Word# -> State# s -> State# s
go Int#
i Word#
carry State# s
s
         | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
># Int#
sz)  = State# s
s
         | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
==# Int#
sz) = MutableWordArray# s -> Word# -> Int# -> State# s -> State# s
forall s.
MutableWordArray# s -> Word# -> Int# -> State# s -> State# s
mwaWriteOrShrink MutableWordArray# s
mwa Word#
carry Int#
i State# s
s
         | Word#
0## <- Word#
carry       = -- copy higher remaining words and shrink the mwa
                                case MutableWordArray# s
-> Int# -> WordArray# -> Int# -> Int# -> State# s -> State# s
forall s.
MutableByteArray# s
-> Int# -> WordArray# -> Int# -> Int# -> State# s -> State# s
mwaArrayCopy# MutableWordArray# s
mwa Int#
i WordArray#
wa Int#
i (Int#
sz Int# -> Int# -> Int#
-# Int#
i) State# s
s of
                                    State# s
s2 -> MutableWordArray# s -> Int# -> State# s -> State# s
forall s. MutableByteArray# s -> Int# -> State# s -> State# s
mwaShrink# MutableWordArray# s
mwa Int#
1# State# s
s2
         | Bool
True               = let !(# Word#
l,Int#
c #) = Word# -> Word# -> (# Word#, Int# #)
addWordC# (WordArray# -> Int# -> Word#
indexWordArray# WordArray#
wa Int#
i) Word#
carry
                                in case MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaWrite# MutableWordArray# s
mwa Int#
i Word#
l State# s
s of
                                    State# s
s2 -> Int# -> Word# -> State# s -> State# s
go (Int#
i Int# -> Int# -> Int#
+# Int#
1#) (Int# -> Word#
int2Word# Int#
c) State# s
s2

-- | Write the most-significant Word:
--    * if it is 0: shrink the array of 1 Word
--    * otherwise: write it
mwaWriteOrShrink :: MutableWordArray# s -> Word# -> Int# -> State# s -> State# s
mwaWriteOrShrink :: forall s.
MutableWordArray# s -> Word# -> Int# -> State# s -> State# s
mwaWriteOrShrink MutableWordArray# s
mwa Word#
0## Int#
_i State# s
s = MutableWordArray# s -> Int# -> State# s -> State# s
forall s. MutableByteArray# s -> Int# -> State# s -> State# s
mwaShrink# MutableWordArray# s
mwa Int#
1# State# s
s
mwaWriteOrShrink MutableWordArray# s
mwa  Word#
w   Int#
i State# s
s = MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaWrite# MutableWordArray# s
mwa Int#
i Word#
w State# s
s

-- | Compute the index of the most-significant Word and write it.
mwaWriteMostSignificant :: MutableWordArray# s -> Word# -> State# s -> State# s
mwaWriteMostSignificant :: forall s. MutableWordArray# s -> Word# -> State# s -> State# s
mwaWriteMostSignificant MutableWordArray# s
mwa Word#
w State# s
s =
   case MutableWordArray# s -> State# s -> (# State# s, Int# #)
forall s. MutableWordArray# s -> State# s -> (# State# s, Int# #)
mwaSize# MutableWordArray# s
mwa State# s
s of
      (# State# s
s', Int#
sz #) -> MutableWordArray# s -> Word# -> Int# -> State# s -> State# s
forall s.
MutableWordArray# s -> Word# -> Int# -> State# s -> State# s
mwaWriteOrShrink MutableWordArray# s
mwa Word#
w (Int#
sz Int# -> Int# -> Int#
-# Int#
1#) State# s
s'

-- | MutableWordArray <- zipWith op wa1 wa2
--
-- Required output: Size(MutableWordArray) = min Size(wa1) Size(wa2)
mwaInitArrayBinOp :: MutableWordArray# s -> WordArray# -> WordArray# -> (Word# -> Word# -> Word#) -> State# s -> State#s
mwaInitArrayBinOp :: forall s.
MutableWordArray# s
-> WordArray#
-> WordArray#
-> (Word# -> Word# -> Word#)
-> State# s
-> State# s
mwaInitArrayBinOp MutableWordArray# s
mwa WordArray#
wa WordArray#
wb Word# -> Word# -> Word#
op State# s
s = Int# -> State# s -> State# s
go Int#
0# State# s
s
   where
      !sz :: Int#
sz = Int# -> Int# -> Int#
minI# (WordArray# -> Int#
wordArraySize# WordArray#
wa) (WordArray# -> Int#
wordArraySize# WordArray#
wb)
      go :: Int# -> State# s -> State# s
go Int#
i State# s
s'
         | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
==# Int#
sz) = State# s
s'
         | Bool
True =
            case WordArray# -> Int# -> Word#
indexWordArray# WordArray#
wa Int#
i Word# -> Word# -> Word#
`op` WordArray# -> Int# -> Word#
indexWordArray# WordArray#
wb Int#
i of
               Word#
v -> case MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaWrite# MutableWordArray# s
mwa Int#
i Word#
v State# s
s' of
                  State# s
s'' -> Int# -> State# s -> State# s
go (Int#
i Int# -> Int# -> Int#
+# Int#
1#) State# s
s''

-- | Write an element of the MutableWordArray
mwaWrite# :: MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaWrite# :: forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaWrite# = MutableByteArray# s -> Int# -> Word# -> State# s -> State# s
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
writeWordArray#

-- | Fill some part of a MutableWordArray with the given Word#
mwaFill# :: MutableWordArray# s -> Word# -> Word# -> Word# -> State# s -> State# s
mwaFill# :: forall s.
MutableWordArray# s
-> Word# -> Word# -> Word# -> State# s -> State# s
mwaFill# MutableWordArray# s
_   Word#
_ Word#
_   Word#
0## State# s
s = State# s
s
mwaFill# MutableWordArray# s
mwa Word#
v Word#
off Word#
n   State# s
s = case MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaWrite# MutableWordArray# s
mwa (Word# -> Int#
word2Int# Word#
off) Word#
v State# s
s of
   State# s
s' -> MutableWordArray# s
-> Word# -> Word# -> Word# -> State# s -> State# s
forall s.
MutableWordArray# s
-> Word# -> Word# -> Word# -> State# s -> State# s
mwaFill# MutableWordArray# s
mwa Word#
v (Word#
off Word# -> Word# -> Word#
`plusWord#` Word#
1##) (Word#
n Word# -> Word# -> Word#
`minusWord#` Word#
1##) State# s
s'

-- | Add Word# inplace (a the specified offset) in the mwa with carry propagation.
mwaAddInplaceWord# :: MutableWordArray# d -> Int# -> Word# -> State# d -> State# d
mwaAddInplaceWord# :: forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaAddInplaceWord#   MutableWordArray# d
_ Int#
_ Word#
0## State# d
s = State# d
s
mwaAddInplaceWord# MutableWordArray# d
mwa Int#
i Word#
y   State# d
s = case MutableWordArray# d -> Int# -> State# d -> (# State# d, Word# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
readWordArray# MutableWordArray# d
mwa Int#
i State# d
s of
   (# State# d
s1, Word#
x #) -> let !(# Word#
h,Word#
l #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
x Word#
y
                  in case MutableWordArray# d -> Int# -> Word# -> State# d -> State# d
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaWrite# MutableWordArray# d
mwa Int#
i Word#
l State# d
s1 of
                        State# d
s2 -> MutableWordArray# d -> Int# -> Word# -> State# d -> State# d
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaAddInplaceWord# MutableWordArray# d
mwa (Int#
i Int# -> Int# -> Int#
+# Int#
1#) Word#
h State# d
s2

-- | Sub Word# inplace (at the specified offset) in the mwa with carry
-- propagation.
--
-- Return False# on underflow
mwaSubInplaceWord#
   :: MutableWordArray# d
   -> Int#
   -> Word#
   -> State# d
   -> (# State# d, Bool# #)
mwaSubInplaceWord# :: forall d.
MutableWordArray# d
-> Int# -> Word# -> State# d -> (# State# d, Int# #)
mwaSubInplaceWord# MutableWordArray# d
mwa Int#
ii Word#
iw State# d
s1 = case MutableWordArray# d -> State# d -> (# State# d, Int# #)
forall s. MutableWordArray# s -> State# s -> (# State# s, Int# #)
mwaSize# MutableWordArray# d
mwa State# d
s1 of
   (# State# d
is, Int#
sz #) ->
      let
         go :: Int# -> Word# -> State# d -> (# State# d, Int# #)
go Int#
_ Word#
0## State# d
s = (# State# d
s, Int#
1# #) -- no underflow
         go Int#
i Word#
y   State# d
s
            | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
>=# Int#
sz) = (# State# d
s, Int#
0# #) -- underflow
            | Bool
True = case MutableWordArray# d -> Int# -> State# d -> (# State# d, Word# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
readWordArray# MutableWordArray# d
mwa Int#
i State# d
s of
               (# State# d
s1, Word#
x #) -> let !(# Word#
l,Int#
h #) = Word# -> Word# -> (# Word#, Int# #)
subWordC# Word#
x Word#
y
                  in case MutableWordArray# d -> Int# -> Word# -> State# d -> State# d
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaWrite# MutableWordArray# d
mwa Int#
i Word#
l State# d
s1 of
                     State# d
s2 -> Int# -> Word# -> State# d -> (# State# d, Int# #)
go (Int#
i Int# -> Int# -> Int#
+# Int#
1#) (Int# -> Word#
int2Word# Int#
h) State# d
s2
      in Int# -> Word# -> State# d -> (# State# d, Int# #)
go Int#
ii Word#
iw State# d
is


-- | Trim `a` of `k` less significant limbs and then compare the result with `b`
--
-- "mwa" doesn't need to be trimmed
mwaTrimCompare :: Int# -> MutableWordArray# s -> WordArray# -> State# s -> (# State# s, Ordering #)
mwaTrimCompare :: forall s.
Int#
-> MutableWordArray# s
-> WordArray#
-> State# s
-> (# State# s, Ordering #)
mwaTrimCompare Int#
k MutableWordArray# s
mwa WordArray#
wb State# s
s1
   | (# State# s
s, Int#
szA #) <- MutableWordArray# s -> State# s -> (# State# s, Int# #)
forall s. MutableWordArray# s -> State# s -> (# State# s, Int# #)
mwaSize# MutableWordArray# s
mwa State# s
s1
   , Int#
szB <- WordArray# -> Int#
wordArraySize# WordArray#
wb
   =
     let
      go :: Int# -> State# s -> (# State# s, Ordering #)
go Int#
i State# s
s
         | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
<# Int#
0#) = (# State# s
s, Ordering
EQ #)
         | Bool
True = case MutableWordArray# s -> Int# -> State# s -> (# State# s, Word# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
readWordArray# MutableWordArray# s
mwa (Int#
i Int# -> Int# -> Int#
+# Int#
k) State# s
s of
            (# State# s
s2, Word#
ai #) ->
               let bi :: Word#
bi = if Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
>=# Int#
szB)
                           then Word#
0##
                           else WordArray# -> Int# -> Word#
indexWordArray# WordArray#
wb Int#
i
               in if | Int# -> Bool
isTrue# (Word#
ai Word# -> Word# -> Int#
`gtWord#` Word#
bi) -> (# State# s
s2, Ordering
GT #)
                     | Int# -> Bool
isTrue# (Word#
bi Word# -> Word# -> Int#
`gtWord#` Word#
ai) -> (# State# s
s2, Ordering
LT #)
                     | Bool
True                      -> Int# -> State# s -> (# State# s, Ordering #)
go (Int#
i Int# -> Int# -> Int#
-# Int#
1#) State# s
s2

      szTrimA :: Int#
szTrimA = Int#
szA Int# -> Int# -> Int#
-# Int#
k

     in if | Int# -> Bool
isTrue# (Int#
szTrimA Int# -> Int# -> Int#
<# Int#
szB) -> (# State# s
s, Ordering
LT #)
           | Bool
True                     -> Int# -> State# s -> (# State# s, Ordering #)
go (Int#
szA Int# -> Int# -> Int#
-# Int#
k Int# -> Int# -> Int#
-# Int#
1#) State# s
s


-- | Sub array inplace (at the specified offset) in the mwa with carry propagation.
--
-- We don't trim the resulting array!
--
-- Return False# on underflow.
mwaSubInplaceArray :: MutableWordArray# d -> Int# -> WordArray# -> State# d -> (# State# d, Bool# #)
mwaSubInplaceArray :: forall d.
MutableWordArray# d
-> Int# -> WordArray# -> State# d -> (# State# d, Int# #)
mwaSubInplaceArray MutableWordArray# d
mwa Int#
off WordArray#
wb = Int# -> State# d -> (# State# d, Int# #)
go (WordArray# -> Int#
wordArraySize# WordArray#
wb Int# -> Int# -> Int#
-# Int#
1#)
   where
      go :: Int# -> State# d -> (# State# d, Int# #)
go Int#
i State# d
s
         | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
<# Int#
0#) = (# State# d
s, Int#
1# #) -- no underflow
         | Bool
True
         = case MutableWordArray# d
-> Int# -> Word# -> State# d -> (# State# d, Int# #)
forall d.
MutableWordArray# d
-> Int# -> Word# -> State# d -> (# State# d, Int# #)
mwaSubInplaceWord# MutableWordArray# d
mwa (Int#
off Int# -> Int# -> Int#
+# Int#
i) (WordArray# -> Int# -> Word#
indexWordArray# WordArray#
wb Int#
i) State# d
s of
            (# State# d
s2, Int#
1# #) -> Int# -> State# d -> (# State# d, Int# #)
go (Int#
i Int# -> Int# -> Int#
-# Int#
1#) State# d
s2
            (# State# d
s2, Int#
_  #) -> (# State# d
s2, Int#
0# #) -- underflow

-- | Add array inplace (a the specified offset) in the mwa with carry propagation.
--
-- Upper bound of the result mutable aray is not checked against overflow.
mwaAddInplaceArray :: MutableWordArray# d -> Int# -> WordArray# -> State# d -> State# d
mwaAddInplaceArray :: forall d.
MutableWordArray# d -> Int# -> WordArray# -> State# d -> State# d
mwaAddInplaceArray MutableWordArray# d
mwa Int#
off WordArray#
wb = Int# -> Word# -> State# d -> State# d
go Int#
0# Word#
0##
   where
      !maxi :: Int#
maxi = WordArray# -> Int#
wordArraySize# WordArray#
wb
      go :: Int# -> Word# -> State# d -> State# d
go Int#
i Word#
c State# d
s
         | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
==# Int#
maxi) = MutableWordArray# d -> Int# -> Word# -> State# d -> State# d
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
mwaAddInplaceWord# MutableWordArray# d
mwa (Int#
i Int# -> Int# -> Int#
+# Int#
off) Word#
c State# d
s
         | Bool
True
         = case MutableWordArray# d -> Int# -> State# d -> (# State# d, Word# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
readWordArray# MutableWordArray# d
mwa (Int#
i Int# -> Int# -> Int#
+# Int#
off) State# d
s of
            (# State# d
s, Word#
v #) -> case Word# -> Word# -> Word# -> (# Word#, Word# #)
plusWord3# Word#
v (WordArray# -> Int# -> Word#
indexWordArray# WordArray#
wb Int#
i) Word#
c of
               (# Word#
c', Word#
v' #) -> case MutableWordArray# d -> Int# -> Word# -> State# d -> State# d
forall s.
MutableWordArray# s -> Int# -> Word# -> State# s -> State# s
writeWordArray# MutableWordArray# d
mwa (Int#
i Int# -> Int# -> Int#
+# Int#
off) Word#
v' State# d
s of
                  State# d
s -> Int# -> Word# -> State# d -> State# d
go (Int#
i Int# -> Int# -> Int#
+# Int#
1#) Word#
c' State# d
s

-- | Sub array inplace (at the specified offset) in the mwa with carry propagation.
--
-- We don't trim the resulting array!
--
-- Return False# on underflow.
mwaSubInplaceMutableArray :: MutableWordArray# d -> Int# -> MutableWordArray# d -> State# d -> (# State# d, Bool# #)
mwaSubInplaceMutableArray :: forall d.
MutableWordArray# d
-> Int# -> MutableWordArray# d -> State# d -> (# State# d, Int# #)
mwaSubInplaceMutableArray MutableWordArray# d
mwa Int#
off MutableWordArray# d
mwb State# d
s0 =
   case MutableWordArray# d -> State# d -> (# State# d, Int# #)
forall s. MutableWordArray# s -> State# s -> (# State# s, Int# #)
mwaSize# MutableWordArray# d
mwb State# d
s0 of
      (# State# d
s1, Int#
szB #) -> Int# -> State# d -> (# State# d, Int# #)
go (Int#
szB Int# -> Int# -> Int#
-# Int#
1#) State# d
s1
   where
      go :: Int# -> State# d -> (# State# d, Int# #)
go Int#
i State# d
s
         | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
<# Int#
0#) = (# State# d
s, Int#
1# #) -- no underflow
         | Bool
True
         = case MutableWordArray# d -> Int# -> State# d -> (# State# d, Word# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
readWordArray# MutableWordArray# d
mwb Int#
i State# d
s of
            (# State# d
s1, Word#
bi #) -> case MutableWordArray# d
-> Int# -> Word# -> State# d -> (# State# d, Int# #)
forall d.
MutableWordArray# d
-> Int# -> Word# -> State# d -> (# State# d, Int# #)
mwaSubInplaceWord# MutableWordArray# d
mwa (Int#
off Int# -> Int# -> Int#
+# Int#
i) Word#
bi State# d
s1 of
               (# State# d
s2, Int#
1# #) -> Int# -> State# d -> (# State# d, Int# #)
go (Int#
i Int# -> Int# -> Int#
-# Int#
1#) State# d
s2
               (# State# d
s2, Int#
_  #) -> (# State# d
s2, Int#
0# #) -- underflow

-- | Sub an array inplace and then trim zeroes
--
-- Don't check overflow. The caller must ensure that a>=b
mwaSubInplaceArrayTrim :: MutableWordArray# d -> Int# -> WordArray# -> State# d -> State# d
mwaSubInplaceArrayTrim :: forall d.
MutableWordArray# d -> Int# -> WordArray# -> State# d -> State# d
mwaSubInplaceArrayTrim MutableWordArray# d
mwa Int#
off WordArray#
wb State# d
s =
   case MutableWordArray# d
-> Int# -> WordArray# -> State# d -> (# State# d, Int# #)
forall d.
MutableWordArray# d
-> Int# -> WordArray# -> State# d -> (# State# d, Int# #)
mwaSubInplaceArray MutableWordArray# d
mwa Int#
off WordArray#
wb State# d
s of
      (# State# d
s', Int#
_ #) -> MutableWordArray# d -> State# d -> State# d
forall s. MutableByteArray# s -> State# s -> State# s
mwaTrimZeroes# MutableWordArray# d
mwa State# d
s'


-- | Read an indexed Word in the MutableWordArray. If the index is out-of-bound,
-- return zero.
mwaReadOrZero :: MutableWordArray# s -> Int# -> State# s  -> (# State# s, Word# #)
mwaReadOrZero :: forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
mwaReadOrZero MutableWordArray# s
mwa Int#
i State# s
s = case MutableWordArray# s -> State# s -> (# State# s, Int# #)
forall s. MutableWordArray# s -> State# s -> (# State# s, Int# #)
mwaSize# MutableWordArray# s
mwa State# s
s of
   (# State# s
s2, Int#
sz #)
      | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
>=# Int#
sz) -> (# State# s
s2, Word#
0## #)
      | Int# -> Bool
isTrue# (Int#
i Int# -> Int# -> Int#
<# Int#
0#)  -> (# State# s
s2, Word#
0## #)
      | Bool
True               -> MutableWordArray# s -> Int# -> State# s -> (# State# s, Word# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
readWordArray# MutableWordArray# s
mwa Int#
i State# s
s2

mwaRead# :: MutableWordArray# s -> Int# -> State# s -> (# State# s, Word# #)
mwaRead# :: forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
mwaRead# = MutableByteArray# s -> Int# -> State# s -> (# State# s, Word# #)
forall d.
MutableByteArray# d -> Int# -> State# d -> (# State# d, Word# #)
readWordArray#