{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE StrictData #-}
{-# LANGUAGE UnboxedTuples #-}
{-# OPTIONS_GHC -funbox-strict-fields #-}

-----------------------------------------------------------------------------
---- |
---- Module      :  Data.WideWord.Word256
----
---- Maintainer  :  erikd@mega-nerd.com
---- Stability   :  experimental
---- Portability :  non-portable (GHC extensions and primops)
----
---- This module provides an opaque unsigned 256 bit value with the usual set
---- of typeclass instances one would expect for a fixed width unsigned integer
---- type.
---- Operations like addition, subtraction and multiplication etc provide a
---- "modulo 2^256" result as one would expect from a fixed width unsigned word.
-------------------------------------------------------------------------------

#include <MachDeps.h>

module Data.WideWord.Word256
  ( Word256 (..)
  , showHexWord256
  , zeroWord256
  ) where

import Control.DeepSeq (NFData (..))

import Data.Bits (Bits (..), FiniteBits (..), shiftL)
import Data.Data (Data, Typeable)
import Data.Ix (Ix)
#if ! MIN_VERSION_base(4,11,0)
import Data.Semigroup ((<>))
#endif

import Foreign.Ptr (Ptr, castPtr)
import Foreign.Storable (Storable (..))

import GHC.Base (Int (..))
import GHC.Enum (predError, succError)
import GHC.Exts ((*#), (+#), Int#, State#, ByteArray#, MutableByteArray#, Addr#)
import GHC.Generics
import GHC.Real ((%))
import GHC.Word (Word64 (..), Word32)

import Data.WideWord.Compat

#if WORD_SIZE_IN_BITS < 64
import GHC.IntWord64
#endif

import Numeric (showHex)

import Data.Primitive.Types (Prim (..), defaultSetByteArray#, defaultSetOffAddr#)
import Data.Hashable (Hashable,hashWithSalt)

data Word256 = Word256
  { Word256 -> Word64
word256hi :: !Word64
  , Word256 -> Word64
word256m1 :: !Word64
  , Word256 -> Word64
word256m0 :: !Word64
  , Word256 -> Word64
word256lo :: !Word64
  }
  deriving (Word256 -> Word256 -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Word256 -> Word256 -> Bool
$c/= :: Word256 -> Word256 -> Bool
== :: Word256 -> Word256 -> Bool
$c== :: Word256 -> Word256 -> Bool
Eq, Typeable Word256
Word256 -> DataType
Word256 -> Constr
(forall b. Data b => b -> b) -> Word256 -> Word256
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Word256 -> u
forall u. (forall d. Data d => d -> u) -> Word256 -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Word256 -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Word256 -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Word256
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Word256 -> c Word256
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Word256)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Word256)
gmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
gmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
gmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Word256 -> m Word256
gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Word256 -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Word256 -> u
gmapQ :: forall u. (forall d. Data d => d -> u) -> Word256 -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Word256 -> [u]
gmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Word256 -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Word256 -> r
gmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Word256 -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Word256 -> r
gmapT :: (forall b. Data b => b -> b) -> Word256 -> Word256
$cgmapT :: (forall b. Data b => b -> b) -> Word256 -> Word256
dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Word256)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Word256)
dataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Word256)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Word256)
dataTypeOf :: Word256 -> DataType
$cdataTypeOf :: Word256 -> DataType
toConstr :: Word256 -> Constr
$ctoConstr :: Word256 -> Constr
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Word256
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Word256
gfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Word256 -> c Word256
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Word256 -> c Word256
Data, forall x. Rep Word256 x -> Word256
forall x. Word256 -> Rep Word256 x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Word256 x -> Word256
$cfrom :: forall x. Word256 -> Rep Word256 x
Generic, Ord Word256
(Word256, Word256) -> Int
(Word256, Word256) -> [Word256]
(Word256, Word256) -> Word256 -> Bool
(Word256, Word256) -> Word256 -> Int
forall a.
Ord a
-> ((a, a) -> [a])
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Int)
-> ((a, a) -> a -> Bool)
-> ((a, a) -> Int)
-> ((a, a) -> Int)
-> Ix a
unsafeRangeSize :: (Word256, Word256) -> Int
$cunsafeRangeSize :: (Word256, Word256) -> Int
rangeSize :: (Word256, Word256) -> Int
$crangeSize :: (Word256, Word256) -> Int
inRange :: (Word256, Word256) -> Word256 -> Bool
$cinRange :: (Word256, Word256) -> Word256 -> Bool
unsafeIndex :: (Word256, Word256) -> Word256 -> Int
$cunsafeIndex :: (Word256, Word256) -> Word256 -> Int
index :: (Word256, Word256) -> Word256 -> Int
$cindex :: (Word256, Word256) -> Word256 -> Int
range :: (Word256, Word256) -> [Word256]
$crange :: (Word256, Word256) -> [Word256]
Ix, Typeable)

instance Hashable Word256 where
  hashWithSalt :: Int -> Word256 -> Int
hashWithSalt Int
s (Word256 Word64
a1 Word64
a2 Word64
a3 Word64
a4) =
    Int
s forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Word64
a1 forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Word64
a2 forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Word64
a3 forall a. Hashable a => Int -> a -> Int
`hashWithSalt` Word64
a4

showHexWord256 :: Word256 -> String
showHexWord256 :: Word256 -> String
showHexWord256 (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0)
  | Word64
a3 forall a. Eq a => a -> a -> Bool
== Word64
0 = if Word64
a2 forall a. Eq a => a -> a -> Bool
== Word64
0
      then if Word64
a1 forall a. Eq a => a -> a -> Bool
== Word64
0
        then forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a0 String
""
        else forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a1 String
zeros0 forall a. [a] -> [a] -> [a]
++ forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a0 String
""
      else forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a2 String
zeros1 forall a. [a] -> [a] -> [a]
++ forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a1 String
zeros0 forall a. [a] -> [a] -> [a]
++ forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a0 String
""
  | Bool
otherwise =
         forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a3 String
zeros2 forall a. [a] -> [a] -> [a]
++ forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a2 String
zeros1
      forall a. [a] -> [a] -> [a]
++ forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a1 String
zeros0 forall a. [a] -> [a] -> [a]
++ forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a0 String
""
  where
    h0 :: String
h0 = forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a0 String
""
    h1 :: String
h1 = forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a1 String
""
    h2 :: String
h2 = forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a2 String
""
    zeros0 :: String
zeros0 = forall a. Int -> a -> [a]
replicate (Int
16 forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length String
h0) Char
'0'
    zeros1 :: String
zeros1 = forall a. Int -> a -> [a]
replicate (Int
16 forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length String
h1) Char
'0'
    zeros2 :: String
zeros2 = forall a. Int -> a -> [a]
replicate (Int
16 forall a. Num a => a -> a -> a
- forall (t :: * -> *) a. Foldable t => t a -> Int
length String
h2) Char
'0'

instance Show Word256 where
  show :: Word256 -> String
show = forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. Word256 -> Integer
toInteger256

instance Read Word256 where
  readsPrec :: Int -> ReadS Word256
readsPrec Int
p String
s = [(Integer -> Word256
fromInteger256 (Integer
x :: Integer), String
r) | (Integer
x, String
r) <- forall a. Read a => Int -> ReadS a
readsPrec Int
p String
s]

instance Ord Word256 where
  compare :: Word256 -> Word256 -> Ordering
compare = Word256 -> Word256 -> Ordering
compare256

instance Bounded Word256 where
  minBound :: Word256
minBound = Word256
zeroWord256
  maxBound :: Word256
maxBound = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 forall a. Bounded a => a
maxBound forall a. Bounded a => a
maxBound forall a. Bounded a => a
maxBound forall a. Bounded a => a
maxBound

instance Enum Word256 where
  succ :: Word256 -> Word256
succ = Word256 -> Word256
succ256
  pred :: Word256 -> Word256
pred = Word256 -> Word256
pred256
  toEnum :: Int -> Word256
toEnum = Int -> Word256
toEnum256
  fromEnum :: Word256 -> Int
fromEnum = Word256 -> Int
fromEnum256

instance Num Word256 where
  + :: Word256 -> Word256 -> Word256
(+) = Word256 -> Word256 -> Word256
plus256
  (-) = Word256 -> Word256 -> Word256
minus256
  * :: Word256 -> Word256 -> Word256
(*) = Word256 -> Word256 -> Word256
times256
  negate :: Word256 -> Word256
negate = Word256 -> Word256
negate256
  abs :: Word256 -> Word256
abs = forall a. a -> a
id
  signum :: Word256 -> Word256
signum = Word256 -> Word256
signum256
  fromInteger :: Integer -> Word256
fromInteger = Integer -> Word256
fromInteger256

instance Bits Word256 where
  .&. :: Word256 -> Word256 -> Word256
(.&.) = Word256 -> Word256 -> Word256
and256
  .|. :: Word256 -> Word256 -> Word256
(.|.) = Word256 -> Word256 -> Word256
or256
  xor :: Word256 -> Word256 -> Word256
xor = Word256 -> Word256 -> Word256
xor256
  complement :: Word256 -> Word256
complement = Word256 -> Word256
complement256
  shiftL :: Word256 -> Int -> Word256
shiftL = Word256 -> Int -> Word256
shiftL256
  unsafeShiftL :: Word256 -> Int -> Word256
unsafeShiftL = Word256 -> Int -> Word256
shiftL256
  shiftR :: Word256 -> Int -> Word256
shiftR = Word256 -> Int -> Word256
shiftR256
  unsafeShiftR :: Word256 -> Int -> Word256
unsafeShiftR = Word256 -> Int -> Word256
shiftR256
  rotateL :: Word256 -> Int -> Word256
rotateL = Word256 -> Int -> Word256
rotateL256
  rotateR :: Word256 -> Int -> Word256
rotateR = Word256 -> Int -> Word256
rotateR256

  bitSize :: Word256 -> Int
bitSize Word256
_ = Int
256
  bitSizeMaybe :: Word256 -> Maybe Int
bitSizeMaybe Word256
_ = forall a. a -> Maybe a
Just Int
256
  isSigned :: Word256 -> Bool
isSigned Word256
_ = Bool
False

  testBit :: Word256 -> Int -> Bool
testBit = Word256 -> Int -> Bool
testBit256
  bit :: Int -> Word256
bit = Int -> Word256
bit256

  popCount :: Word256 -> Int
popCount = Word256 -> Int
popCount256

instance FiniteBits Word256 where
  finiteBitSize :: Word256 -> Int
finiteBitSize Word256
_ = Int
256
  countLeadingZeros :: Word256 -> Int
countLeadingZeros = Word256 -> Int
countLeadingZeros256
  countTrailingZeros :: Word256 -> Int
countTrailingZeros = Word256 -> Int
countTrailingZeros256

instance Real Word256 where
  toRational :: Word256 -> Rational
toRational Word256
x = Word256 -> Integer
toInteger256 Word256
x forall a. Integral a => a -> a -> Ratio a
% Integer
1

instance Integral Word256 where
  quot :: Word256 -> Word256 -> Word256
quot Word256
n Word256
d = forall a b. (a, b) -> a
fst (Word256 -> Word256 -> (Word256, Word256)
quotRem256 Word256
n Word256
d)
  rem :: Word256 -> Word256 -> Word256
rem Word256
n Word256
d = forall a b. (a, b) -> b
snd (Word256 -> Word256 -> (Word256, Word256)
quotRem256 Word256
n Word256
d)
  div :: Word256 -> Word256 -> Word256
div Word256
n Word256
d = forall a b. (a, b) -> a
fst (Word256 -> Word256 -> (Word256, Word256)
quotRem256 Word256
n Word256
d)
  mod :: Word256 -> Word256 -> Word256
mod Word256
n Word256
d = forall a b. (a, b) -> b
snd (Word256 -> Word256 -> (Word256, Word256)
quotRem256 Word256
n Word256
d)
  quotRem :: Word256 -> Word256 -> (Word256, Word256)
quotRem = Word256 -> Word256 -> (Word256, Word256)
quotRem256
  divMod :: Word256 -> Word256 -> (Word256, Word256)
divMod = Word256 -> Word256 -> (Word256, Word256)
quotRem256
  toInteger :: Word256 -> Integer
toInteger = Word256 -> Integer
toInteger256

instance Storable Word256 where
  sizeOf :: Word256 -> Int
sizeOf Word256
w = Int# -> Int
I# (Word256 -> Int#
sizeOf256# Word256
w)
  alignment :: Word256 -> Int
alignment Word256
w = Int# -> Int
I# (Word256 -> Int#
alignment256# Word256
w)
  peek :: Ptr Word256 -> IO Word256
peek = Ptr Word256 -> IO Word256
peek256
  peekElemOff :: Ptr Word256 -> Int -> IO Word256
peekElemOff = Ptr Word256 -> Int -> IO Word256
peekElemOff256
  poke :: Ptr Word256 -> Word256 -> IO ()
poke = Ptr Word256 -> Word256 -> IO ()
poke256
  pokeElemOff :: Ptr Word256 -> Int -> Word256 -> IO ()
pokeElemOff = Ptr Word256 -> Int -> Word256 -> IO ()
pokeElemOff256

instance NFData Word256 where
  -- The fields are already strict and unpacked, so do nothing.
  rnf :: Word256 -> ()
rnf !Word256
_ = ()

instance Prim Word256 where
  sizeOf# :: Word256 -> Int#
sizeOf#         = Word256 -> Int#
sizeOf256#
  alignment# :: Word256 -> Int#
alignment#      = Word256 -> Int#
alignment256#
  indexByteArray# :: ByteArray# -> Int# -> Word256
indexByteArray# = ByteArray# -> Int# -> Word256
indexByteArray256#
  readByteArray# :: forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Word256 #)
readByteArray#  = forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Word256 #)
readByteArray256#
  writeByteArray# :: forall s.
MutableByteArray# s -> Int# -> Word256 -> State# s -> State# s
writeByteArray# = forall s.
MutableByteArray# s -> Int# -> Word256 -> State# s -> State# s
writeByteArray256#
  setByteArray# :: forall s.
MutableByteArray# s
-> Int# -> Int# -> Word256 -> State# s -> State# s
setByteArray#   = forall s.
MutableByteArray# s
-> Int# -> Int# -> Word256 -> State# s -> State# s
setByteArray256#
  indexOffAddr# :: Addr# -> Int# -> Word256
indexOffAddr#   = Addr# -> Int# -> Word256
indexOffAddr256#
  readOffAddr# :: forall s. Addr# -> Int# -> State# s -> (# State# s, Word256 #)
readOffAddr#    = forall s. Addr# -> Int# -> State# s -> (# State# s, Word256 #)
readOffAddr256#
  writeOffAddr# :: forall s. Addr# -> Int# -> Word256 -> State# s -> State# s
writeOffAddr#   = forall s. Addr# -> Int# -> Word256 -> State# s -> State# s
writeOffAddr256#
  setOffAddr# :: forall s. Addr# -> Int# -> Int# -> Word256 -> State# s -> State# s
setOffAddr#     = forall s. Addr# -> Int# -> Int# -> Word256 -> State# s -> State# s
setOffAddr256#
  {-# INLINE sizeOf# #-}
  {-# INLINE alignment# #-}
  {-# INLINE indexByteArray# #-}
  {-# INLINE readByteArray# #-}
  {-# INLINE writeByteArray# #-}
  {-# INLINE setByteArray# #-}
  {-# INLINE indexOffAddr# #-}
  {-# INLINE readOffAddr# #-}
  {-# INLINE writeOffAddr# #-}
  {-# INLINE setOffAddr# #-}

-- -----------------------------------------------------------------------------
-- Rewrite rules.

{-# RULES
"fromIntegral :: Word256 -> Word256" fromIntegral = id :: Word256 -> Word256

"fromIntegral :: Int -> Word256"     fromIntegral = fromInt
"fromIntegral :: Word -> Word256"    fromIntegral = fromWord
"fromIntegral :: Word32 -> Word256"  fromIntegral = fromWord32
"fromIntegral :: Word64 -> Word256"  fromIntegral = Word256 0 0 0

"fromIntegral :: Word256 -> Int"     fromIntegral = toInt
"fromIntegral :: Word256 -> Word"    fromIntegral = toWord
"fromIntegral :: Word256 -> Word32"  fromIntegral = toWord32
"fromIntegral :: Word256 -> Word64"  fromIntegral = \(Word256 _ _ _ w) -> w
  #-}

{-# INLINE fromInt #-}
fromInt :: Int -> Word256
fromInt :: Int -> Word256
fromInt = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral

{-# INLINE fromWord #-}
fromWord :: Word -> Word256
fromWord :: Word -> Word256
fromWord = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral

{-# INLINE fromWord32 #-}
fromWord32 :: Word32 -> Word256
fromWord32 :: Word32 -> Word256
fromWord32 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (Integral a, Num b) => a -> b
fromIntegral

{-# INLINE toInt #-}
toInt :: Word256 -> Int
toInt :: Word256 -> Int
toInt (Word256 Word64
_ Word64
_ Word64
_ Word64
w) = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w

{-# INLINE toWord #-}
toWord :: Word256 -> Word
toWord :: Word256 -> Word
toWord (Word256 Word64
_ Word64
_ Word64
_ Word64
w) = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w

{-# INLINE toWord32 #-}
toWord32 :: Word256 -> Word32
toWord32 :: Word256 -> Word32
toWord32 (Word256 Word64
_ Word64
_ Word64
_ Word64
w) = forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
w

-- -----------------------------------------------------------------------------
-- Functions for `Ord` instance.

compare256 :: Word256 -> Word256 -> Ordering
compare256 :: Word256 -> Word256 -> Ordering
compare256 (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) (Word256 Word64
b3 Word64
b2 Word64
b1 Word64
b0) =
  forall a. Ord a => a -> a -> Ordering
compare Word64
a3 Word64
b3 forall a. Semigroup a => a -> a -> a
<> forall a. Ord a => a -> a -> Ordering
compare Word64
a2 Word64
b2 forall a. Semigroup a => a -> a -> a
<> forall a. Ord a => a -> a -> Ordering
compare Word64
a1 Word64
b1 forall a. Semigroup a => a -> a -> a
<> forall a. Ord a => a -> a -> Ordering
compare Word64
a0 Word64
b0

-- -----------------------------------------------------------------------------
-- Functions for `Enum` instance.

succ256 :: Word256 -> Word256
succ256 :: Word256 -> Word256
succ256 (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0)
  | Word64
a0 forall a. Eq a => a -> a -> Bool
== forall a. Bounded a => a
maxBound = if Word64
a1 forall a. Eq a => a -> a -> Bool
== forall a. Bounded a => a
maxBound
      then if Word64
a2 forall a. Eq a => a -> a -> Bool
== forall a. Bounded a => a
maxBound
        then if Word64
a3 forall a. Eq a => a -> a -> Bool
== forall a. Bounded a => a
maxBound
          then forall a. String -> a
succError String
"Word256"
          else Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64
a3 forall a. Num a => a -> a -> a
+ Word64
1) Word64
0 Word64
0 Word64
0
        else Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 (Word64
a2 forall a. Num a => a -> a -> a
+ Word64
1) Word64
0 Word64
0
      else Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 Word64
a2 (Word64
a1 forall a. Num a => a -> a -> a
+ Word64
1) Word64
0
  | Bool
otherwise = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 Word64
a2 Word64
a1 (Word64
a0 forall a. Num a => a -> a -> a
+ Word64
1)


pred256 :: Word256 -> Word256
pred256 :: Word256 -> Word256
pred256 (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0)
  | Word64
a0 forall a. Eq a => a -> a -> Bool
== Word64
0 = if Word64
a1 forall a. Eq a => a -> a -> Bool
== Word64
0
      then if Word64
a2 forall a. Eq a => a -> a -> Bool
== Word64
0
        then if Word64
a3 forall a. Eq a => a -> a -> Bool
== Word64
0
          then forall a. String -> a
predError String
"Word256"
          else Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64
a3 forall a. Num a => a -> a -> a
- Word64
1) forall a. Bounded a => a
maxBound forall a. Bounded a => a
maxBound forall a. Bounded a => a
maxBound
        else Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 (Word64
a2 forall a. Num a => a -> a -> a
- Word64
1) forall a. Bounded a => a
maxBound forall a. Bounded a => a
maxBound
      else Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 Word64
a2 (Word64
a1 forall a. Num a => a -> a -> a
- Word64
1) forall a. Bounded a => a
maxBound
  | Bool
otherwise = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a3 Word64
a2 Word64
a1 (Word64
a0 forall a. Num a => a -> a -> a
- Word64
1)


{-# INLINABLE toEnum256 #-}
toEnum256 :: Int -> Word256
toEnum256 :: Int -> Word256
toEnum256 Int
i = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 (forall a. Enum a => Int -> a
toEnum Int
i)

{-# INLINABLE fromEnum256 #-}
fromEnum256 :: Word256 -> Int
fromEnum256 :: Word256 -> Int
fromEnum256 (Word256 Word64
_ Word64
_ Word64
_ Word64
a0) = forall a. Enum a => a -> Int
fromEnum Word64
a0

-- -----------------------------------------------------------------------------
-- Functions for `Num` instance.

{-# INLINABLE plus256 #-}
plus256 :: Word256 -> Word256 -> Word256
plus256 :: Word256 -> Word256 -> Word256
plus256 (Word256 (W64# Word#
a3) (W64# Word#
a2) (W64# Word#
a1) (W64# Word#
a0))
        (Word256 (W64# Word#
b3) (W64# Word#
b2) (W64# Word#
b1) (W64# Word#
b0)) =
  Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word# -> Word64
W64# Word#
s3) (Word# -> Word64
W64# Word#
s2) (Word# -> Word64
W64# Word#
s1) (Word# -> Word64
W64# Word#
s0)
  where
    !(# Word#
c1, Word#
s0 #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
a0 Word#
b0
    !(# Word#
c2a, Word#
s1a #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
a1 Word#
b1
    !(# Word#
c2b, Word#
s1 #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
s1a Word#
c1
    c2 :: Word#
c2 = Word# -> Word# -> Word#
plusWord# Word#
c2a Word#
c2b
    !(# Word#
c3a, Word#
s2a #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
a2 Word#
b2
    !(# Word#
c3b, Word#
s2 #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
s2a Word#
c2
    c3 :: Word#
c3 = Word# -> Word# -> Word#
plusWord# Word#
c3a Word#
c3b
    s3 :: Word#
s3 = Word# -> Word# -> Word#
plusWord# Word#
a3 (Word# -> Word# -> Word#
plusWord# Word#
b3 Word#
c3)

{-# INLINABLE minus256 #-}
minus256 :: Word256 -> Word256 -> Word256
minus256 :: Word256 -> Word256 -> Word256
minus256 (Word256 (W64# Word#
a3) (W64# Word#
a2) (W64# Word#
a1) (W64# Word#
a0))
         (Word256 (W64# Word#
b3) (W64# Word#
b2) (W64# Word#
b1) (W64# Word#
b0)) =
  Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word# -> Word64
W64# Word#
s3) (Word# -> Word64
W64# Word#
s2) (Word# -> Word64
W64# Word#
s1) (Word# -> Word64
W64# Word#
s0)
  where
    !(# Word#
s0, Int#
v1 #) = Word# -> Word# -> (# Word#, Int# #)
subWordC# Word#
a0 Word#
b0
    !(# Word#
s1, Int#
v2 #) =
      case Int# -> Int#
compatCaseOnIntLiteral# Int#
v1 of
        Int#
0# -> Word# -> Word# -> (# Word#, Int# #)
subWordC# Word#
a1 Word#
b1
        Int#
_ ->
          case Word# -> Word#
compatCaseOnWordLiteral# Word#
a1 of
            Word#
0## -> (# Word# -> Word# -> Word#
minusWord# (Word# -> Word#
compatWordLiteral# Word#
0xFFFFFFFFFFFFFFFF##) Word#
b1, Int# -> Int#
compatIntLiteral# Int#
1# #)
            Word#
_ -> Word# -> Word# -> (# Word#, Int# #)
subWordC# (Word# -> Word# -> Word#
minusWord# Word#
a1 (Word# -> Word#
compatWordLiteral# Word#
1##)) Word#
b1
    !(# Word#
s2, Int#
v3 #) =
      case Int# -> Int#
compatCaseOnIntLiteral# Int#
v2 of
        Int#
0# -> Word# -> Word# -> (# Word#, Int# #)
subWordC# Word#
a2 Word#
b2
        Int#
_ ->
          case Word# -> Word#
compatCaseOnWordLiteral# Word#
a2 of
            Word#
0## -> (# Word# -> Word# -> Word#
minusWord# (Word# -> Word#
compatWordLiteral# Word#
0xFFFFFFFFFFFFFFFF##) Word#
b2, Int# -> Int#
compatIntLiteral# Int#
1# #)
            Word#
_ -> Word# -> Word# -> (# Word#, Int# #)
subWordC# (Word# -> Word# -> Word#
minusWord# Word#
a2 (Word# -> Word#
compatWordLiteral# Word#
1##)) Word#
b2
    !s3 :: Word#
s3 =
      case Int# -> Int#
compatCaseOnIntLiteral# Int#
v3 of
        Int#
0# -> Word# -> Word# -> Word#
minusWord# Word#
a3 Word#
b3
        Int#
_ -> Word# -> Word# -> Word#
minusWord# (Word# -> Word# -> Word#
minusWord# Word#
a3 (Word# -> Word#
compatWordLiteral# Word#
1##)) Word#
b3

times256 :: Word256 -> Word256 -> Word256
times256 :: Word256 -> Word256 -> Word256
times256 (Word256 (W64# Word#
a3) (W64# Word#
a2) (W64# Word#
a1) (W64# Word#
a0))
         (Word256 (W64# Word#
b3) (W64# Word#
b2) (W64# Word#
b1) (W64# Word#
b0)) =
  Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word# -> Word64
W64# Word#
r3) (Word# -> Word64
W64# Word#
r2) (Word# -> Word64
W64# Word#
r1) (Word# -> Word64
W64# Word#
r0)
  where
    !(# Word#
c00, Word#
p00 #) = Word# -> Word# -> (# Word#, Word# #)
timesWord2# Word#
a0 Word#
b0
    !(# Word#
c01, Word#
p01 #) = Word# -> Word# -> (# Word#, Word# #)
timesWord2# Word#
a0 Word#
b1
    !(# Word#
c02, Word#
p02 #) = Word# -> Word# -> (# Word#, Word# #)
timesWord2# Word#
a0 Word#
b2
    !p03 :: Word#
p03 = Word# -> Word# -> Word#
timesWord# Word#
a0 Word#
b3
    !(# Word#
c10, Word#
p10 #) = Word# -> Word# -> (# Word#, Word# #)
timesWord2# Word#
a1 Word#
b0
    !(# Word#
c11, Word#
p11 #) = Word# -> Word# -> (# Word#, Word# #)
timesWord2# Word#
a1 Word#
b1
    !p12 :: Word#
p12 = Word# -> Word# -> Word#
timesWord# Word#
a1 Word#
b2
    !(# Word#
c20, Word#
p20 #) = Word# -> Word# -> (# Word#, Word# #)
timesWord2# Word#
a2 Word#
b0
    !p21 :: Word#
p21 = Word# -> Word# -> Word#
timesWord# Word#
a2 Word#
b1
    !p30 :: Word#
p30 = Word# -> Word# -> Word#
timesWord# Word#
a3 Word#
b0
    !r0 :: Word#
r0 = Word#
p00
    !c1 :: Word#
c1 = Word#
c00
    !(# Word#
c2x, Word#
r1a #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
p01 Word#
p10
    !(# Word#
c2y, Word#
r1b #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
r1a Word#
c1
    !(# Word#
c3w, Word#
c2 #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
c2x Word#
c2y
    !r1 :: Word#
r1 = Word#
r1b
    !(# Word#
c3x, Word#
r2a #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
p11 Word#
p20
    !(# Word#
c3y, Word#
r2b #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
p02 Word#
r2a
    !(# Word#
c3z, Word#
r2c #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
r2b Word#
c2
    !(# Word#
c3s, Word#
r2d #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
r2c Word#
c01
    !(# Word#
c3t, Word#
r2e #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
r2d Word#
c10
    !r2 :: Word#
r2 = Word#
r2e
    !r3 :: Word#
r3 = Word#
p30 Word# -> Word# -> Word#
`plusWord#` Word#
p21 Word# -> Word# -> Word#
`plusWord#` Word#
p12 Word# -> Word# -> Word#
`plusWord#`
         Word#
p03 Word# -> Word# -> Word#
`plusWord#` Word#
c3w Word# -> Word# -> Word#
`plusWord#` Word#
c3x Word# -> Word# -> Word#
`plusWord#`
         Word#
c3y Word# -> Word# -> Word#
`plusWord#` Word#
c3z Word# -> Word# -> Word#
`plusWord#` Word#
c3s Word# -> Word# -> Word#
`plusWord#`
         Word#
c3t Word# -> Word# -> Word#
`plusWord#` Word#
c02 Word# -> Word# -> Word#
`plusWord#` Word#
c11 Word# -> Word# -> Word#
`plusWord#`
         Word#
c20

{-# INLINABLE negate256 #-}
negate256 :: Word256 -> Word256
negate256 :: Word256 -> Word256
negate256 (Word256 (W64# Word#
a3) (W64# Word#
a2) (W64# Word#
a1) (W64# Word#
a0)) =
  case Word# -> Word# -> (# Word#, Word# #)
plusWord2# (Word# -> Word#
not# Word#
a0) (Word# -> Word#
compatWordLiteral# Word#
1##) of
    (# Word#
c1, Word#
s0 #) -> case Word# -> Word# -> (# Word#, Word# #)
plusWord2# (Word# -> Word#
not# Word#
a1) Word#
c1 of
      (# Word#
c2, Word#
s1 #) -> case Word# -> Word# -> (# Word#, Word# #)
plusWord2# (Word# -> Word#
not# Word#
a2) Word#
c2 of
        (# Word#
c3, Word#
s2 #) -> case Word# -> Word# -> Word#
plusWord# (Word# -> Word#
not# Word#
a3) Word#
c3 of
          Word#
s3 -> Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word# -> Word64
W64# Word#
s3) (Word# -> Word64
W64# Word#
s2) (Word# -> Word64
W64# Word#
s1) (Word# -> Word64
W64# Word#
s0)

{-# INLINABLE signum256 #-}
signum256 :: Word256 -> Word256
signum256 :: Word256 -> Word256
signum256 (Word256 (W64# Word#
a) (W64# Word#
b) (W64# Word#
c) (W64# Word#
d))
  | Word# -> Bool
isZeroWord# Word#
a
  , Word# -> Bool
isZeroWord# Word#
b
  , Word# -> Bool
isZeroWord# Word#
c
  , Word# -> Bool
isZeroWord# Word#
d
  = Word256
zeroWord256
  | Bool
otherwise = Word256
oneWord256

fromInteger256 :: Integer -> Word256
fromInteger256 :: Integer -> Word256
fromInteger256 Integer
i = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
  (forall a. Num a => Integer -> a
fromInteger forall a b. (a -> b) -> a -> b
$ Integer
i forall a. Bits a => a -> Int -> a
`shiftR` Int
192)
  (forall a. Num a => Integer -> a
fromInteger forall a b. (a -> b) -> a -> b
$ Integer
i forall a. Bits a => a -> Int -> a
`shiftR` Int
128)
  (forall a. Num a => Integer -> a
fromInteger forall a b. (a -> b) -> a -> b
$ Integer
i forall a. Bits a => a -> Int -> a
`shiftR` Int
64)
  (forall a. Num a => Integer -> a
fromInteger Integer
i)

-- -----------------------------------------------------------------------------
-- Functions for `Bits` instance.

{-# INLINABLE and256 #-}
and256 :: Word256 -> Word256 -> Word256
and256 :: Word256 -> Word256 -> Word256
and256 (Word256 (W64# Word#
a3) (W64# Word#
a2) (W64# Word#
a1) (W64# Word#
a0))
       (Word256 (W64# Word#
b3) (W64# Word#
b2) (W64# Word#
b1) (W64# Word#
b0)) =
  Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word# -> Word64
W64# (Word# -> Word# -> Word#
and# Word#
a3 Word#
b3)) (Word# -> Word64
W64# (Word# -> Word# -> Word#
and# Word#
a2 Word#
b2))
          (Word# -> Word64
W64# (Word# -> Word# -> Word#
and# Word#
a1 Word#
b1)) (Word# -> Word64
W64# (Word# -> Word# -> Word#
and# Word#
a0 Word#
b0))

{-# INLINABLE or256 #-}
or256 :: Word256 -> Word256 -> Word256
or256 :: Word256 -> Word256 -> Word256
or256 (Word256 (W64# Word#
a3) (W64# Word#
a2) (W64# Word#
a1) (W64# Word#
a0))
      (Word256 (W64# Word#
b3) (W64# Word#
b2) (W64# Word#
b1) (W64# Word#
b0)) =
  Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word# -> Word64
W64# (Word# -> Word# -> Word#
or# Word#
a3 Word#
b3)) (Word# -> Word64
W64# (Word# -> Word# -> Word#
or# Word#
a2 Word#
b2))
          (Word# -> Word64
W64# (Word# -> Word# -> Word#
or# Word#
a1 Word#
b1)) (Word# -> Word64
W64# (Word# -> Word# -> Word#
or# Word#
a0 Word#
b0))

{-# INLINABLE xor256 #-}
xor256 :: Word256 -> Word256 -> Word256
xor256 :: Word256 -> Word256 -> Word256
xor256 (Word256 (W64# Word#
a3) (W64# Word#
a2) (W64# Word#
a1) (W64# Word#
a0))
       (Word256 (W64# Word#
b3) (W64# Word#
b2) (W64# Word#
b1) (W64# Word#
b0)) =
  Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word# -> Word64
W64# (Word# -> Word# -> Word#
xor# Word#
a3 Word#
b3)) (Word# -> Word64
W64# (Word# -> Word# -> Word#
xor# Word#
a2 Word#
b2))
          (Word# -> Word64
W64# (Word# -> Word# -> Word#
xor# Word#
a1 Word#
b1)) (Word# -> Word64
W64# (Word# -> Word# -> Word#
xor# Word#
a0 Word#
b0))

{-# INLINABLE complement256 #-}
complement256 :: Word256 -> Word256
complement256 :: Word256 -> Word256
complement256 (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
  (forall a. Bits a => a -> a
complement Word64
a3) (forall a. Bits a => a -> a
complement Word64
a2)
  (forall a. Bits a => a -> a
complement Word64
a1) (forall a. Bits a => a -> a
complement Word64
a0)

-- Probably not worth inlining this.
shiftL256 :: Word256 -> Int -> Word256
shiftL256 :: Word256 -> Int -> Word256
shiftL256 w :: Word256
w@(Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) Int
s
  | Int
s forall a. Ord a => a -> a -> Bool
< Int
0 Bool -> Bool -> Bool
|| Int
s forall a. Ord a => a -> a -> Bool
>= Int
256 = Word256
zeroWord256
  | Int
s forall a. Eq a => a -> a -> Bool
== Int
0 = Word256
w
  | Int
s forall a. Ord a => a -> a -> Bool
> Int
192 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 (Word64
a0 forall a. Bits a => a -> Int -> a
`shiftL` (Int
s forall a. Num a => a -> a -> a
- Int
192)) Word64
0 Word64
0 Word64
0
  | Int
s forall a. Eq a => a -> a -> Bool
== Int
192 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a0 Word64
0 Word64
0 Word64
0
  | Int
s forall a. Ord a => a -> a -> Bool
> Int
128 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
      (Word64
a1 forall a. Bits a => a -> Int -> a
`shiftL` (Int
s forall a. Num a => a -> a -> a
- Int
128) forall a. Num a => a -> a -> a
+ Word64
a0 forall a. Bits a => a -> Int -> a
`shiftR` (Int
192 forall a. Num a => a -> a -> a
- Int
s))
      (Word64
a0 forall a. Bits a => a -> Int -> a
`shiftL` (Int
s forall a. Num a => a -> a -> a
- Int
128))
      Word64
0 Word64
0
  | Int
s forall a. Eq a => a -> a -> Bool
== Int
128 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a1 Word64
a0 Word64
0 Word64
0
  | Int
s forall a. Ord a => a -> a -> Bool
> Int
64 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
      (Word64
a2 forall a. Bits a => a -> Int -> a
`shiftL` (Int
s forall a. Num a => a -> a -> a
- Int
64) forall a. Num a => a -> a -> a
+ Word64
a1 forall a. Bits a => a -> Int -> a
`shiftR` (Int
128 forall a. Num a => a -> a -> a
- Int
s))
      (Word64
a1 forall a. Bits a => a -> Int -> a
`shiftL` (Int
s forall a. Num a => a -> a -> a
- Int
64) forall a. Num a => a -> a -> a
+ Word64
a0 forall a. Bits a => a -> Int -> a
`shiftR` (Int
128 forall a. Num a => a -> a -> a
- Int
s))
      (Word64
a0 forall a. Bits a => a -> Int -> a
`shiftL` (Int
s forall a. Num a => a -> a -> a
- Int
64))
      Word64
0
  | Int
s forall a. Eq a => a -> a -> Bool
== Int
64 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a2 Word64
a1 Word64
a0 Word64
0
  | Bool
otherwise = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
      (Word64
a3 forall a. Bits a => a -> Int -> a
`shiftL` Int
s forall a. Num a => a -> a -> a
+ Word64
a2 forall a. Bits a => a -> Int -> a
`shiftR` (Int
64 forall a. Num a => a -> a -> a
- Int
s))
      (Word64
a2 forall a. Bits a => a -> Int -> a
`shiftL` Int
s forall a. Num a => a -> a -> a
+ Word64
a1 forall a. Bits a => a -> Int -> a
`shiftR` (Int
64 forall a. Num a => a -> a -> a
- Int
s))
      (Word64
a1 forall a. Bits a => a -> Int -> a
`shiftL` Int
s forall a. Num a => a -> a -> a
+ Word64
a0 forall a. Bits a => a -> Int -> a
`shiftR` (Int
64 forall a. Num a => a -> a -> a
- Int
s))
      (Word64
a0 forall a. Bits a => a -> Int -> a
`shiftL` Int
s)

shiftR256 :: Word256 -> Int -> Word256
shiftR256 :: Word256 -> Int -> Word256
shiftR256 w :: Word256
w@(Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) Int
s
  | Int
s forall a. Ord a => a -> a -> Bool
< Int
0 = Word256
zeroWord256
  | Int
s forall a. Eq a => a -> a -> Bool
== Int
0 = Word256
w
  | Int
s forall a. Ord a => a -> a -> Bool
>= Int
256 = Word256
zeroWord256
  | Int
s forall a. Ord a => a -> a -> Bool
> Int
192 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 (Word64
a3 forall a. Bits a => a -> Int -> a
`shiftR` (Int
s forall a. Num a => a -> a -> a
- Int
192))
  | Int
s forall a. Eq a => a -> a -> Bool
== Int
192 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 Word64
a3
  | Int
s forall a. Ord a => a -> a -> Bool
> Int
128 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0
      (Word64
a3 forall a. Bits a => a -> Int -> a
`shiftR` (Int
s forall a. Num a => a -> a -> a
- Int
128))
      (Word64
a2 forall a. Bits a => a -> Int -> a
`shiftR` (Int
s forall a. Num a => a -> a -> a
- Int
128) forall a. Num a => a -> a -> a
+ Word64
a3 forall a. Bits a => a -> Int -> a
`shiftL` (Int
192 forall a. Num a => a -> a -> a
- Int
s))
  | Int
s forall a. Eq a => a -> a -> Bool
== Int
128 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
a3 Word64
a2
  | Int
s forall a. Ord a => a -> a -> Bool
> Int
64 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0
      (Word64
a3 forall a. Bits a => a -> Int -> a
`shiftR` (Int
s forall a. Num a => a -> a -> a
- Int
64))
      (Word64
a2 forall a. Bits a => a -> Int -> a
`shiftR` (Int
s forall a. Num a => a -> a -> a
- Int
64) forall a. Num a => a -> a -> a
+ Word64
a3 forall a. Bits a => a -> Int -> a
`shiftL` (Int
128 forall a. Num a => a -> a -> a
- Int
s))
      (Word64
a1 forall a. Bits a => a -> Int -> a
`shiftR` (Int
s forall a. Num a => a -> a -> a
- Int
64) forall a. Num a => a -> a -> a
+ Word64
a2 forall a. Bits a => a -> Int -> a
`shiftL` (Int
128 forall a. Num a => a -> a -> a
- Int
s))
  | Int
s forall a. Eq a => a -> a -> Bool
== Int
64 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
a3 Word64
a2 Word64
a1
  | Bool
otherwise = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
      (Word64
a3 forall a. Bits a => a -> Int -> a
`shiftR` Int
s)
      (Word64
a2 forall a. Bits a => a -> Int -> a
`shiftR` Int
s forall a. Num a => a -> a -> a
+ Word64
a3 forall a. Bits a => a -> Int -> a
`shiftL` (Int
64 forall a. Num a => a -> a -> a
- Int
s))
      (Word64
a1 forall a. Bits a => a -> Int -> a
`shiftR` Int
s forall a. Num a => a -> a -> a
+ Word64
a2 forall a. Bits a => a -> Int -> a
`shiftL` (Int
64 forall a. Num a => a -> a -> a
- Int
s))
      (Word64
a0 forall a. Bits a => a -> Int -> a
`shiftR` Int
s forall a. Num a => a -> a -> a
+ Word64
a1 forall a. Bits a => a -> Int -> a
`shiftL` (Int
64 forall a. Num a => a -> a -> a
- Int
s))

rotateL256 :: Word256 -> Int -> Word256
rotateL256 :: Word256 -> Int -> Word256
rotateL256 w :: Word256
w@(Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) Int
r
  | Int
r forall a. Ord a => a -> a -> Bool
< Int
0 = Word256
zeroWord256
  | Int
r forall a. Eq a => a -> a -> Bool
== Int
0 = Word256
w
  | Int
r forall a. Ord a => a -> a -> Bool
>= Int
256 = Word256 -> Int -> Word256
rotateL256 Word256
w (Int
r forall a. Integral a => a -> a -> a
`mod` Int
256)
  | Int
r forall a. Ord a => a -> a -> Bool
>= Int
64 = Word256 -> Int -> Word256
rotateL256 (Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a2 Word64
a1 Word64
a0 Word64
a3) (Int
r forall a. Num a => a -> a -> a
- Int
64)
  | Bool
otherwise =
      Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
s3 Word64
s2 Word64
s1 Word64
s0
      where
        s0 :: Word64
s0 = Word64
a0 forall a. Bits a => a -> Int -> a
`shiftL` Int
r forall a. Num a => a -> a -> a
+ Word64
a3 forall a. Bits a => a -> Int -> a
`shiftR` (Int
64 forall a. Num a => a -> a -> a
- Int
r)
        s1 :: Word64
s1 = Word64
a1 forall a. Bits a => a -> Int -> a
`shiftL` Int
r forall a. Num a => a -> a -> a
+ Word64
a0 forall a. Bits a => a -> Int -> a
`shiftR` (Int
64 forall a. Num a => a -> a -> a
- Int
r)
        s2 :: Word64
s2 = Word64
a2 forall a. Bits a => a -> Int -> a
`shiftL` Int
r forall a. Num a => a -> a -> a
+ Word64
a1 forall a. Bits a => a -> Int -> a
`shiftR` (Int
64 forall a. Num a => a -> a -> a
- Int
r)
        s3 :: Word64
s3 = Word64
a3 forall a. Bits a => a -> Int -> a
`shiftL` Int
r forall a. Num a => a -> a -> a
+ Word64
a2 forall a. Bits a => a -> Int -> a
`shiftR` (Int
64 forall a. Num a => a -> a -> a
- Int
r)

rotateR256 :: Word256 -> Int -> Word256
rotateR256 :: Word256 -> Int -> Word256
rotateR256 w :: Word256
w@(Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) Int
r
  | Int
r forall a. Ord a => a -> a -> Bool
< Int
0 = Word256 -> Int -> Word256
rotateR256 Word256
w (Int
256 forall a. Num a => a -> a -> a
- (forall a. Num a => a -> a
abs Int
r forall a. Integral a => a -> a -> a
`mod` Int
256))
  | Int
r forall a. Eq a => a -> a -> Bool
== Int
0 = Word256
w
  | Int
r forall a. Ord a => a -> a -> Bool
>= Int
256 = Word256 -> Int -> Word256
rotateR256 Word256
w (Int
r forall a. Integral a => a -> a -> a
`mod` Int
256)
  | Int
r forall a. Ord a => a -> a -> Bool
>= Int
64 = Word256 -> Int -> Word256
rotateR256 (Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
a0 Word64
a3 Word64
a2 Word64
a1) (Int
r forall a. Num a => a -> a -> a
- Int
64)
  | Bool
otherwise =
      Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
s3 Word64
s2 Word64
s1 Word64
s0
      where
        s0 :: Word64
s0 = Word64
a0 forall a. Bits a => a -> Int -> a
`shiftR` Int
r forall a. Num a => a -> a -> a
+ Word64
a1 forall a. Bits a => a -> Int -> a
`shiftL` (Int
64 forall a. Num a => a -> a -> a
- Int
r)
        s1 :: Word64
s1 = Word64
a1 forall a. Bits a => a -> Int -> a
`shiftR` Int
r forall a. Num a => a -> a -> a
+ Word64
a2 forall a. Bits a => a -> Int -> a
`shiftL` (Int
64 forall a. Num a => a -> a -> a
- Int
r)
        s2 :: Word64
s2 = Word64
a2 forall a. Bits a => a -> Int -> a
`shiftR` Int
r forall a. Num a => a -> a -> a
+ Word64
a3 forall a. Bits a => a -> Int -> a
`shiftL` (Int
64 forall a. Num a => a -> a -> a
- Int
r)
        s3 :: Word64
s3 = Word64
a3 forall a. Bits a => a -> Int -> a
`shiftR` Int
r forall a. Num a => a -> a -> a
+ Word64
a0 forall a. Bits a => a -> Int -> a
`shiftL` (Int
64 forall a. Num a => a -> a -> a
- Int
r)

testBit256 :: Word256 -> Int -> Bool
testBit256 :: Word256 -> Int -> Bool
testBit256 (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) Int
i
  | Int
i forall a. Ord a => a -> a -> Bool
< Int
0 = Bool
False
  | Int
i forall a. Ord a => a -> a -> Bool
>= Int
256 = Bool
False
  | Int
i forall a. Ord a => a -> a -> Bool
>= Int
192 = forall a. Bits a => a -> Int -> Bool
testBit Word64
a3 (Int
i forall a. Num a => a -> a -> a
- Int
192)
  | Int
i forall a. Ord a => a -> a -> Bool
>= Int
128 = forall a. Bits a => a -> Int -> Bool
testBit Word64
a2 (Int
i forall a. Num a => a -> a -> a
- Int
128)
  | Int
i forall a. Ord a => a -> a -> Bool
>= Int
64 = forall a. Bits a => a -> Int -> Bool
testBit Word64
a1 (Int
i forall a. Num a => a -> a -> a
- Int
64)
  | Bool
otherwise = forall a. Bits a => a -> Int -> Bool
testBit Word64
a0 Int
i

bit256 :: Int -> Word256
bit256 :: Int -> Word256
bit256 Int
indx
  | Int
indx forall a. Ord a => a -> a -> Bool
< Int
0 = Word256
zeroWord256
  | Int
indx forall a. Ord a => a -> a -> Bool
>= Int
256 = Word256
zeroWord256
  | Bool
otherwise = Word256 -> Int -> Word256
shiftL256 Word256
oneWord256 Int
indx

popCount256 :: Word256 -> Int
popCount256 :: Word256 -> Int
popCount256 (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) =
  forall a. Bits a => a -> Int
popCount Word64
a3 forall a. Num a => a -> a -> a
+ forall a. Bits a => a -> Int
popCount Word64
a2 forall a. Num a => a -> a -> a
+ forall a. Bits a => a -> Int
popCount Word64
a1 forall a. Num a => a -> a -> a
+ forall a. Bits a => a -> Int
popCount Word64
a0

-- -----------------------------------------------------------------------------
-- Functions for `FiniteBits` instance.

countLeadingZeros256 :: Word256 -> Int
countLeadingZeros256 :: Word256 -> Int
countLeadingZeros256 (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) =
  case forall b. FiniteBits b => b -> Int
countLeadingZeros Word64
a3 of
    Int
64 -> case forall b. FiniteBits b => b -> Int
countLeadingZeros Word64
a2 of
      Int
64 -> case forall b. FiniteBits b => b -> Int
countLeadingZeros Word64
a1 of
        Int
64 -> Int
192 forall a. Num a => a -> a -> a
+ forall b. FiniteBits b => b -> Int
countLeadingZeros Word64
a0
        Int
res -> Int
128 forall a. Num a => a -> a -> a
+ Int
res
      Int
res -> Int
64 forall a. Num a => a -> a -> a
+ Int
res
    Int
res -> Int
res

countTrailingZeros256 :: Word256 -> Int
countTrailingZeros256 :: Word256 -> Int
countTrailingZeros256 (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) =
  case forall b. FiniteBits b => b -> Int
countTrailingZeros Word64
a0 of
    Int
64 -> case forall b. FiniteBits b => b -> Int
countTrailingZeros Word64
a1 of
      Int
64 -> case forall b. FiniteBits b => b -> Int
countTrailingZeros Word64
a2 of
        Int
64 -> Int
192 forall a. Num a => a -> a -> a
+ forall b. FiniteBits b => b -> Int
countTrailingZeros Word64
a3
        Int
res -> Int
128 forall a. Num a => a -> a -> a
+ Int
res
      Int
res -> Int
64 forall a. Num a => a -> a -> a
+ Int
res
    Int
res -> Int
res

-- -----------------------------------------------------------------------------
-- Functions for `Integral` instance.

-- TODO: This is inefficient, but the better version is rather
-- tedious to write out.
quotRem256 :: Word256 -> Word256 -> (Word256, Word256)
quotRem256 :: Word256 -> Word256 -> (Word256, Word256)
quotRem256 Word256
a Word256
b =
  let (Integer
x,Integer
y) = forall a. Integral a => a -> a -> (a, a)
quotRem (Word256 -> Integer
toInteger256 Word256
a) (Word256 -> Integer
toInteger256 Word256
b)
   in (Integer -> Word256
fromInteger256 Integer
x, Integer -> Word256
fromInteger256 Integer
y)

toInteger256 :: Word256 -> Integer
toInteger256 :: Word256 -> Integer
toInteger256 (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) =
    (forall a. Integral a => a -> Integer
toInteger Word64
a3 forall a. Bits a => a -> Int -> a
`shiftL` Int
192)
  forall a. Num a => a -> a -> a
+ (forall a. Integral a => a -> Integer
toInteger Word64
a2 forall a. Bits a => a -> Int -> a
`shiftL` Int
128)
  forall a. Num a => a -> a -> a
+ (forall a. Integral a => a -> Integer
toInteger Word64
a1 forall a. Bits a => a -> Int -> a
`shiftL` Int
64)
  forall a. Num a => a -> a -> a
+ forall a. Integral a => a -> Integer
toInteger Word64
a0

-- -----------------------------------------------------------------------------
-- Functions for `Storable` instance.

peek256 :: Ptr Word256 -> IO Word256
peek256 :: Ptr Word256 -> IO Word256
peek256 Ptr Word256
ptr = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) Int
index3
  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) Int
index2
  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) Int
index1
  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) Int
index0

peekElemOff256 :: Ptr Word256 -> Int -> IO Word256
peekElemOff256 :: Ptr Word256 -> Int -> IO Word256
peekElemOff256 Ptr Word256
ptr Int
idx = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256
  forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) (Int
idx2 forall a. Num a => a -> a -> a
+ Int
index3)
  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) (Int
idx2 forall a. Num a => a -> a -> a
+ Int
index2)
  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) (Int
idx2 forall a. Num a => a -> a -> a
+ Int
index1)
  forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) (Int
idx2 forall a. Num a => a -> a -> a
+ Int
index0)
  where idx2 :: Int
idx2 = Int
4 forall a. Num a => a -> a -> a
* Int
idx

poke256 :: Ptr Word256 -> Word256 -> IO ()
poke256 :: Ptr Word256 -> Word256 -> IO ()
poke256 Ptr Word256
ptr (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) = do
  forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) Int
index3 Word64
a3
  forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) Int
index2 Word64
a2
  forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) Int
index1 Word64
a1
  forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) Int
index0 Word64
a0

pokeElemOff256 :: Ptr Word256 -> Int -> Word256 -> IO ()
pokeElemOff256 :: Ptr Word256 -> Int -> Word256 -> IO ()
pokeElemOff256 Ptr Word256
ptr Int
idx (Word256 Word64
a3 Word64
a2 Word64
a1 Word64
a0) = do
  forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) (Int
idx2 forall a. Num a => a -> a -> a
+ Int
index0) Word64
a0
  forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) (Int
idx2 forall a. Num a => a -> a -> a
+ Int
index1) Word64
a1
  forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) (Int
idx2 forall a. Num a => a -> a -> a
+ Int
index2) Word64
a2
  forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (forall a b. Ptr a -> Ptr b
castPtr Ptr Word256
ptr) (Int
idx2 forall a. Num a => a -> a -> a
+ Int
index3) Word64
a3
  where idx2 :: Int
idx2 = Int
4 forall a. Num a => a -> a -> a
* Int
idx

-- -----------------------------------------------------------------------------
-- Functions for `Prim` instance.

{-# INLINE sizeOf256# #-}
sizeOf256# :: Word256 -> Int#
sizeOf256# :: Word256 -> Int#
sizeOf256# Word256
_ = Int#
4# Int# -> Int# -> Int#
*# forall a. Prim a => a -> Int#
sizeOf# (Word64
0 :: Word64)

{-# INLINE alignment256# #-}
alignment256# :: Word256 -> Int#
alignment256# :: Word256 -> Int#
alignment256# Word256
_ = Int#
4# Int# -> Int# -> Int#
*# forall a. Prim a => a -> Int#
alignment# (Word64
0 :: Word64)

{-# INLINE indexByteArray256# #-}
indexByteArray256# :: ByteArray# -> Int# -> Word256
indexByteArray256# :: ByteArray# -> Int# -> Word256
indexByteArray256# ByteArray#
arr# Int#
i# =
  let i2# :: Int#
i2# = Int#
4# Int# -> Int# -> Int#
*# Int#
i#
      w :: Word64
w = forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index3)
      x :: Word64
x = forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index2)
      y :: Word64
y = forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index1)
      z :: Word64
z = forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index0)
  in Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
w Word64
x Word64
y Word64
z

{-# INLINE readByteArray256# #-}
readByteArray256# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Word256 #)
readByteArray256# :: forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Word256 #)
readByteArray256# MutableByteArray# s
arr# Int#
i# =
  \State# s
s0 -> case forall a s.
Prim a =>
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)
readByteArray# MutableByteArray# s
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index3) State# s
s0 of
    (# State# s
s1, Word64
w #) -> case forall a s.
Prim a =>
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)
readByteArray# MutableByteArray# s
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index2) State# s
s1 of
      (# State# s
s2, Word64
x #) -> case forall a s.
Prim a =>
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)
readByteArray# MutableByteArray# s
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index1) State# s
s2 of
        (# State# s
s3, Word64
y #) -> case forall a s.
Prim a =>
MutableByteArray# s -> Int# -> State# s -> (# State# s, a #)
readByteArray# MutableByteArray# s
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index0) State# s
s3 of
          (# State# s
s4, Word64
z #) -> (# State# s
s4, Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
w Word64
x Word64
y Word64
z #)
  where i2# :: Int#
i2# = Int#
4# Int# -> Int# -> Int#
*# Int#
i#

{-# INLINE writeByteArray256# #-}
writeByteArray256# :: MutableByteArray# s -> Int# -> Word256 -> State# s -> State# s
writeByteArray256# :: forall s.
MutableByteArray# s -> Int# -> Word256 -> State# s -> State# s
writeByteArray256# MutableByteArray# s
arr# Int#
i# (Word256 Word64
a Word64
b Word64
c Word64
d) =
  \State# s
s0 -> case forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# s
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index3) Word64
a State# s
s0 of
    State# s
s1 -> case forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# s
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index2) Word64
b State# s
s1 of
      State# s
s2 -> case forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# s
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index1) Word64
c State# s
s2 of
        State# s
s3 -> case forall a s.
Prim a =>
MutableByteArray# s -> Int# -> a -> State# s -> State# s
writeByteArray# MutableByteArray# s
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index0) Word64
d State# s
s3 of
          State# s
s4 -> State# s
s4
  where i2# :: Int#
i2# = Int#
4# Int# -> Int# -> Int#
*# Int#
i#

{-# INLINE setByteArray256# #-}
setByteArray256# :: MutableByteArray# s -> Int# -> Int# -> Word256 -> State# s -> State# s
setByteArray256# :: forall s.
MutableByteArray# s
-> Int# -> Int# -> Word256 -> State# s -> State# s
setByteArray256# = forall a s.
Prim a =>
MutableByteArray# s -> Int# -> Int# -> a -> State# s -> State# s
defaultSetByteArray#

{-# INLINE indexOffAddr256# #-}
indexOffAddr256# :: Addr# -> Int# -> Word256
indexOffAddr256# :: Addr# -> Int# -> Word256
indexOffAddr256# Addr#
arr# Int#
i# =
  let i2# :: Int#
i2# = Int#
4# Int# -> Int# -> Int#
*# Int#
i#
      w :: Word64
w = forall a. Prim a => Addr# -> Int# -> a
indexOffAddr# Addr#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index3)
      x :: Word64
x = forall a. Prim a => Addr# -> Int# -> a
indexOffAddr# Addr#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index2)
      y :: Word64
y = forall a. Prim a => Addr# -> Int# -> a
indexOffAddr# Addr#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index1)
      z :: Word64
z = forall a. Prim a => Addr# -> Int# -> a
indexOffAddr# Addr#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index0)
  in Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
w Word64
x Word64
y Word64
z

{-# INLINE readOffAddr256# #-}
readOffAddr256# :: Addr# -> Int# -> State# s -> (# State# s, Word256 #)
readOffAddr256# :: forall s. Addr# -> Int# -> State# s -> (# State# s, Word256 #)
readOffAddr256# Addr#
arr# Int#
i# =
  \State# s
s0 -> case forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index3) State# s
s0 of
    (# State# s
s1, Word64
w #) -> case forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index2) State# s
s1 of
      (# State# s
s2, Word64
x #) -> case forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index1) State# s
s2 of
        (# State# s
s3, Word64
y #) -> case forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index0) State# s
s3 of
          (# State# s
s4, Word64
z #) -> (# State# s
s4, Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
w Word64
x Word64
y Word64
z #)
  where i2# :: Int#
i2# = Int#
4# Int# -> Int# -> Int#
*# Int#
i#

{-# INLINE writeOffAddr256# #-}
writeOffAddr256# :: Addr# -> Int# -> Word256 -> State# s -> State# s
writeOffAddr256# :: forall s. Addr# -> Int# -> Word256 -> State# s -> State# s
writeOffAddr256# Addr#
arr# Int#
i# (Word256 Word64
a Word64
b Word64
c Word64
d) =
  \State# s
s0 -> case forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index3) Word64
a State# s
s0 of
    State# s
s1 -> case forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index2) Word64
b State# s
s1 of
      State# s
s2 -> case forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index1) Word64
c State# s
s2 of
        State# s
s3 -> case forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index0) Word64
d State# s
s3 of
          State# s
s4 -> State# s
s4
  where i2# :: Int#
i2# = Int#
4# Int# -> Int# -> Int#
*# Int#
i#

{-# INLINE setOffAddr256# #-}
setOffAddr256# :: Addr# -> Int# -> Int# -> Word256 -> State# s -> State# s
setOffAddr256# :: forall s. Addr# -> Int# -> Int# -> Word256 -> State# s -> State# s
setOffAddr256# = forall a s.
Prim a =>
Addr# -> Int# -> Int# -> a -> State# s -> State# s
defaultSetOffAddr#

-- -----------------------------------------------------------------------------
-- Constants.

zeroWord256 :: Word256
zeroWord256 :: Word256
zeroWord256 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 Word64
0

oneWord256 :: Word256
oneWord256 :: Word256
oneWord256 = Word64 -> Word64 -> Word64 -> Word64 -> Word256
Word256 Word64
0 Word64
0 Word64
0 Word64
1

unInt :: Int -> Int#
unInt :: Int -> Int#
unInt (I# Int#
i#) = Int#
i#

-- Use these indices to get the peek/poke ordering endian correct.
index0, index1, index2, index3 :: Int
#if WORDS_BIGENDIAN
index0 = 3
index1 = 2
index2 = 1
index3 = 0
#else
index0 :: Int
index0 = Int
0
index1 :: Int
index1 = Int
1
index2 :: Int
index2 = Int
2
index3 :: Int
index3 = Int
3
#endif