    {-# LANGUAGE CPP                #-}
    {-# LANGUAGE MagicHash          #-}
    {-# LANGUAGE UnboxedTuples      #-}
    {-# LANGUAGE BangPatterns       #-}
    {-# LANGUAGE DeriveDataTypeable #-}
    module Basement.Types.Word128
        ( Word128(..)
        , (+)
        , (-)
        , (*)
        , quot
        , rem
        , bitwiseAnd
        , bitwiseOr
        , bitwiseXor
        , complement
        , shiftL
        , shiftR
        , rotateL
        , rotateR
        , popCount
        , fromNatural
        ) where

    import           GHC.Prim
    import           GHC.Word
    import           GHC.Types
    import qualified Prelude (fromInteger, show, Num(..), quot, rem, mod)
    import           Data.Bits hiding (complement, popCount, bit, testBit
                                      , rotateL, rotateR, shiftL, shiftR)
    import qualified Data.Bits as Bits
    import           Data.Function (on)
    import           Foreign.C
    import           Foreign.Ptr
    import           Foreign.Storable

    import           Basement.Compat.Base
    import           Basement.Compat.Natural
    import           Basement.Compat.Primitive (bool#)
    import           Basement.Numerical.Conversion
    import           Basement.Numerical.Number

    #include "MachDeps.h"

    -- | 128 bits Word
    data Word128 = Word128 {-# UNPACK #-} !Word64
                           {-# UNPACK #-} !Word64
        deriving (Word128 -> Word128 -> Bool
    (Word128 -> Word128 -> Bool)
    -> (Word128 -> Word128 -> Bool) -> Eq Word128
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    /= :: Word128 -> Word128 -> Bool
    $c/= :: Word128 -> Word128 -> Bool
    == :: Word128 -> Word128 -> Bool
    $c== :: Word128 -> Word128 -> Bool
    Eq, Typeable)

    instance Show Word128 where
        show :: Word128 -> String
    show w :: Word128
    w = Natural -> String
    forall a. Show a => a -> String
    Prelude.show (Word128 -> Natural
    forall a. IsNatural a => a -> Natural
    toNatural Word128
    w)
    instance Enum Word128 where
        toEnum :: Int -> Word128
    toEnum i :: Int
    i = Word64 -> Word64 -> Word128
    Word128 0 (Word64 -> Word128) -> Word64 -> Word128
    forall a b. (a -> b) -> a -> b
    $ Int64 -> Word64
    int64ToWord64 (Int -> Int64
    intToInt64 Int
    i)
        fromEnum :: Word128 -> Int
    fromEnum (Word128 _ a0 :: Word64
    a0) = Word -> Int
    wordToInt (Word64 -> Word
    word64ToWord Word64
    a0)
        succ :: Word128 -> Word128
    succ (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0)
            | Word64
    a0 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    forall a. Bounded a => a
    maxBound = Word64 -> Word64 -> Word128
    Word128 (Word64 -> Word64
    forall a. Enum a => a -> a
    succ Word64
    a1) 0
            | Bool
    otherwise      = Word64 -> Word64 -> Word128
    Word128 Word64
    a1        (Word64 -> Word64
    forall a. Enum a => a -> a
    succ Word64
    a0)
        pred :: Word128 -> Word128
    pred (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0)
            | Word64
    a0 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == Word64
    forall a. Bounded a => a
    minBound = Word64 -> Word64 -> Word128
    Word128 (Word64 -> Word64
    forall a. Enum a => a -> a
    pred Word64
    a1) Word64
    forall a. Bounded a => a
    maxBound
            | Bool
    otherwise      = Word64 -> Word64 -> Word128
    Word128 Word64
    a1        (Word64 -> Word64
    forall a. Enum a => a -> a
    pred Word64
    a0)
    instance Bounded Word128 where
        minBound :: Word128
    minBound = Word64 -> Word64 -> Word128
    Word128 Word64
    forall a. Bounded a => a
    minBound Word64
    forall a. Bounded a => a
    minBound
        maxBound :: Word128
    maxBound = Word64 -> Word64 -> Word128
    Word128 Word64
    forall a. Bounded a => a
    maxBound Word64
    forall a. Bounded a => a
    maxBound
    instance Ord Word128 where
        compare :: Word128 -> Word128 -> Ordering
    compare (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) (Word128 b1 :: Word64
    b1 b0 :: Word64
    b0) =
            case Word64 -> Word64 -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word64
    a1 Word64
    b1 of
                EQ -> Word64 -> Word64 -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word64
    a0 Word64
    b0
                r :: Ordering
    r  -> Ordering
    r
        < :: Word128 -> Word128 -> Bool
    (<) (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) (Word128 b1 :: Word64
    b1 b0 :: Word64
    b0) =
            case Word64 -> Word64 -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word64
    a1 Word64
    b1 of
                EQ -> Word64
    a0 Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    < Word64
    b0
                r :: Ordering
    r  -> Ordering
    r Ordering -> Ordering -> Bool
    forall a. Eq a => a -> a -> Bool
    == Ordering
    LT
        <= :: Word128 -> Word128 -> Bool
    (<=) (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) (Word128 b1 :: Word64
    b1 b0 :: Word64
    b0) =
            case Word64 -> Word64 -> Ordering
    forall a. Ord a => a -> a -> Ordering
    compare Word64
    a1 Word64
    b1 of
                EQ -> Word64
    a0 Word64 -> Word64 -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Word64
    b0
                r :: Ordering
    r  -> Ordering
    r Ordering -> Ordering -> Bool
    forall a. Eq a => a -> a -> Bool
    == Ordering
    LT
    instance Storable Word128 where
        sizeOf :: Word128 -> Int
    sizeOf _ = 16
        alignment :: Word128 -> Int
    alignment _ = 16
        peek :: Ptr Word128 -> IO Word128
    peek p :: Ptr Word128
    p = Word64 -> Word64 -> Word128
    Word128 (Word64 -> Word64 -> Word128)
    -> IO Word64 -> IO (Word64 -> Word128)
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Ptr Word64 -> IO Word64
    forall a. Storable a => Ptr a -> IO a
    peek (Ptr Word128 -> Ptr Word64
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word128
    p            )
                         IO (Word64 -> Word128) -> IO Word64 -> IO Word128
    forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
    <*> Ptr Word64 -> IO Word64
    forall a. Storable a => Ptr a -> IO a
    peek (Ptr Word128 -> Ptr Any
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word128
    p Ptr Any -> Int -> Ptr Word64
    forall a b. Ptr a -> Int -> Ptr b
    `plusPtr` 8)
        poke :: Ptr Word128 -> Word128 -> IO ()
    poke p :: Ptr Word128
    p (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) = do
            Ptr Word64 -> Word64 -> IO ()
    forall a. Storable a => Ptr a -> a -> IO ()
    poke (Ptr Word128 -> Ptr Word64
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word128
    p            ) Word64
    a1
            Ptr Word64 -> Word64 -> IO ()
    forall a. Storable a => Ptr a -> a -> IO ()
    poke (Ptr Word128 -> Ptr Any
    forall a b. Ptr a -> Ptr b
    castPtr Ptr Word128
    p Ptr Any -> Int -> Ptr Word64
    forall a b. Ptr a -> Int -> Ptr b
    `plusPtr` 8) Word64
    a0

    instance Integral Word128 where
        fromInteger :: Integer -> Word128
    fromInteger = Integer -> Word128
    literal
    instance HasNegation Word128 where
        negate :: Word128 -> Word128
    negate = Word128 -> Word128
    complement

    instance IsIntegral Word128 where
        toInteger :: Word128 -> Integer
    toInteger (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) =
            (Word64 -> Integer
    forall a. IsIntegral a => a -> Integer
    toInteger Word64
    a1 Integer -> Int -> Integer
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` 64) Integer -> Integer -> Integer
    forall a. Bits a => a -> a -> a
    .|.
            Word64 -> Integer
    forall a. IsIntegral a => a -> Integer
    toInteger Word64
    a0
    instance IsNatural Word128 where
        toNatural :: Word128 -> Natural
    toNatural (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) =
            (Word64 -> Natural
    forall a. IsNatural a => a -> Natural
    toNatural Word64
    a1 Natural -> Int -> Natural
    forall a. Bits a => a -> Int -> a
    `unsafeShiftL` 64) Natural -> Natural -> Natural
    forall a. Bits a => a -> a -> a
    .|.
            Word64 -> Natural
    forall a. IsNatural a => a -> Natural
    toNatural Word64
    a0

    instance Prelude.Num Word128 where
        abs :: Word128 -> Word128
    abs w :: Word128
    w = Word128
    w
        signum :: Word128 -> Word128
    signum w :: Word128
    w@(Word128 a1 :: Word64
    a1 a0 :: Word64
    a0)
            | Word64
    a1 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0 Bool -> Bool -> Bool
    && Word64
    a0 Word64 -> Word64 -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0 = Word128
    w
            | Bool
    otherwise          = Word64 -> Word64 -> Word128
    Word128 0 1
        fromInteger :: Integer -> Word128
    fromInteger = Integer -> Word128
    literal
        + :: Word128 -> Word128 -> Word128
    (+) = Word128 -> Word128 -> Word128
    (+)
        (-) = (-)
        * :: Word128 -> Word128 -> Word128
    (*) = Word128 -> Word128 -> Word128
    (*)

    instance Bits.Bits Word128 where
        .&. :: Word128 -> Word128 -> Word128
    (.&.) = Word128 -> Word128 -> Word128
    bitwiseAnd
        .|. :: Word128 -> Word128 -> Word128
    (.|.) = Word128 -> Word128 -> Word128
    bitwiseOr
        xor :: Word128 -> Word128 -> Word128
    xor   = Word128 -> Word128 -> Word128
    bitwiseXor
        complement :: Word128 -> Word128
    complement = Word128 -> Word128
    complement
        shiftL :: Word128 -> Int -> Word128
    shiftL = Word128 -> Int -> Word128
    shiftL
        shiftR :: Word128 -> Int -> Word128
    shiftR = Word128 -> Int -> Word128
    shiftR
        rotateL :: Word128 -> Int -> Word128
    rotateL = Word128 -> Int -> Word128
    rotateL
        rotateR :: Word128 -> Int -> Word128
    rotateR = Word128 -> Int -> Word128
    rotateR
        bitSize :: Word128 -> Int
    bitSize _ = 128
        bitSizeMaybe :: Word128 -> Maybe Int
    bitSizeMaybe _ = Int -> Maybe Int
    forall a. a -> Maybe a
    Just 128
        isSigned :: Word128 -> Bool
    isSigned _ = Bool
    False
        testBit :: Word128 -> Int -> Bool
    testBit = Word128 -> Int -> Bool
    testBit
        bit :: Int -> Word128
    bit = Int -> Word128
    bit
        popCount :: Word128 -> Int
    popCount = Word128 -> Int
    popCount

    -- | Add 2 Word128
    (+) :: Word128 -> Word128 -> Word128
    #if WORD_SIZE_IN_BITS < 64
    (+) = applyBiWordOnNatural (Prelude.+)
    #else
    + :: Word128 -> Word128 -> Word128
    (+) (Word128 (W64# a1 :: Word#
    a1) (W64# a0 :: Word#
    a0)) (Word128 (W64# b1 :: Word#
    b1) (W64# b0 :: Word#
    b0)) = Word64 -> Word64 -> Word128
    Word128 (Word# -> Word64
    W64# Word#
    s1) (Word# -> Word64
    W64# Word#
    s0)
      where
        !(# carry :: Word#
    carry, s0 :: Word#
    s0 #) = Word# -> Word# -> (# Word#, Word# #)
    plusWord2# Word#
    a0 Word#
    b0
        s1 :: Word#
    s1               = Word# -> Word# -> Word#
    plusWord# (Word# -> Word# -> Word#
    plusWord# Word#
    a1 Word#
    b1) Word#
    carry
    #endif

    -- temporary available until native operation available
    applyBiWordOnNatural :: (Natural -> Natural -> Natural)
                         -> Word128
                         -> Word128
                         -> Word128
    applyBiWordOnNatural :: (Natural -> Natural -> Natural) -> Word128 -> Word128 -> Word128
    applyBiWordOnNatural f :: Natural -> Natural -> Natural
    f a :: Word128
    a b :: Word128
    b = Natural -> Word128
    fromNatural (Natural -> Word128) -> Natural -> Word128
    forall a b. (a -> b) -> a -> b
    $ Natural -> Natural -> Natural
    f (Word128 -> Natural
    forall a. IsNatural a => a -> Natural
    toNatural Word128
    a) (Word128 -> Natural
    forall a. IsNatural a => a -> Natural
    toNatural Word128
    b)

    -- | Subtract 2 Word128
    (-) :: Word128 -> Word128 -> Word128
    (-) a :: Word128
    a b :: Word128
    b
        | Word128
    a Word128 -> Word128 -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Word128
    b    = (Natural -> Natural -> Natural) -> Word128 -> Word128 -> Word128
    applyBiWordOnNatural Natural -> Natural -> Natural
    forall a. Num a => a -> a -> a
    (Prelude.-) Word128
    a Word128
    b
        | Bool
    otherwise = Word128 -> Word128
    complement ((Natural -> Natural -> Natural) -> Word128 -> Word128 -> Word128
    applyBiWordOnNatural Natural -> Natural -> Natural
    forall a. Num a => a -> a -> a
    (Prelude.-) Word128
    b Word128
    a) Word128 -> Word128 -> Word128
    + 1

    -- | Multiplication
    (*) :: Word128 -> Word128 -> Word128
    * :: Word128 -> Word128 -> Word128
    (*) = (Natural -> Natural -> Natural) -> Word128 -> Word128 -> Word128
    applyBiWordOnNatural Natural -> Natural -> Natural
    forall a. Num a => a -> a -> a
    (Prelude.*)

    -- | Division
    quot :: Word128 -> Word128 -> Word128
    quot :: Word128 -> Word128 -> Word128
    quot = (Natural -> Natural -> Natural) -> Word128 -> Word128 -> Word128
    applyBiWordOnNatural Natural -> Natural -> Natural
    forall a. Integral a => a -> a -> a
    Prelude.quot

    -- | Modulo
    rem :: Word128 -> Word128 -> Word128
    rem :: Word128 -> Word128 -> Word128
    rem = (Natural -> Natural -> Natural) -> Word128 -> Word128 -> Word128
    applyBiWordOnNatural Natural -> Natural -> Natural
    forall a. Integral a => a -> a -> a
    Prelude.rem

    -- | Bitwise and
    bitwiseAnd :: Word128 -> Word128 -> Word128
    bitwiseAnd :: Word128 -> Word128 -> Word128
    bitwiseAnd (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) (Word128 b1 :: Word64
    b1 b0 :: Word64
    b0) =
        Word64 -> Word64 -> Word128
    Word128 (Word64
    a1 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .&. Word64
    b1) (Word64
    a0 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .&. Word64
    b0)

    -- | Bitwise or
    bitwiseOr :: Word128 -> Word128 -> Word128
    bitwiseOr :: Word128 -> Word128 -> Word128
    bitwiseOr (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) (Word128 b1 :: Word64
    b1 b0 :: Word64
    b0) =
        Word64 -> Word64 -> Word128
    Word128 (Word64
    a1 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word64
    b1) (Word64
    a0 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. Word64
    b0)

    -- | Bitwise xor
    bitwiseXor :: Word128 -> Word128 -> Word128
    bitwiseXor :: Word128 -> Word128 -> Word128
    bitwiseXor (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) (Word128 b1 :: Word64
    b1 b0 :: Word64
    b0) =
        Word64 -> Word64 -> Word128
    Word128 (Word64
    a1 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `Bits.xor` Word64
    b1) (Word64
    a0 Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    `Bits.xor` Word64
    b0)

    -- | Bitwise complement
    complement :: Word128 -> Word128
    complement :: Word128 -> Word128
    complement (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) = Word64 -> Word64 -> Word128
    Word128 (Word64 -> Word64
    forall a. Bits a => a -> a
    Bits.complement Word64
    a1) (Word64 -> Word64
    forall a. Bits a => a -> a
    Bits.complement Word64
    a0)

    -- | Population count
    popCount :: Word128 -> Int
    popCount :: Word128 -> Int
    popCount (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) = Word64 -> Int
    forall a. Bits a => a -> Int
    Bits.popCount Word64
    a1 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.+ Word64 -> Int
    forall a. Bits a => a -> Int
    Bits.popCount Word64
    a0

    -- | Bitwise Shift Left
    shiftL :: Word128 -> Int -> Word128
    shiftL :: Word128 -> Int -> Word128
    shiftL w :: Word128
    w@(Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) n :: Int
    n
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0 Bool -> Bool -> Bool
    || Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 127 = Word64 -> Word64 -> Word128
    Word128 0 0
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 64          = Word64 -> Word64 -> Word128
    Word128 Word64
    a0 0
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0           = Word128
    w
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >  64          = Word64 -> Word64 -> Word128
    Word128 (Word64
    a0 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- 64)) 0
        | Bool
    otherwise        = Word64 -> Word64 -> Word128
    Word128 ((Word64
    a1 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` Int
    n) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. (Word64
    a0 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` (64 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    n)))
                                     (Word64
    a0 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` Int
    n)

    -- | Bitwise Shift Right
    shiftR :: Word128 -> Int -> Word128
    shiftR :: Word128 -> Int -> Word128
    shiftR w :: Word128
    w@(Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) n :: Int
    n
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0 Bool -> Bool -> Bool
    || Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 127 = Word64 -> Word64 -> Word128
    Word128 0 0
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 64          = Word64 -> Word64 -> Word128
    Word128 0 Word64
    a1
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0           = Word128
    w
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >  64          = Word64 -> Word64 -> Word128
    Word128 0 (Word64
    a1 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- 64))
        | Bool
    otherwise        = Word64 -> Word64 -> Word128
    Word128 (Word64
    a1 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` Int
    n)
                                     ((Word64
    a1 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` (Int -> Int
    inv64 Int
    n)) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. (Word64
    a0 Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` Int
    n))

    -- | Bitwise rotate Left
    rotateL :: Word128 -> Int -> Word128
    rotateL :: Word128 -> Int -> Word128
    rotateL (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) n' :: Int
    n'
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 0    = Word64 -> Word64 -> Word128
    Word128 Word64
    a1 Word64
    a0
        | Int
    n Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == 64   = Word64 -> Word64 -> Word128
    Word128 Word64
    a0 Word64
    a1
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 64    = Word64 -> Word64 -> Word128
    Word128 (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a1 Int
    n Word64
    a0 (Int -> Int
    inv64 Int
    n)) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a0 Int
    n Word64
    a1 (Int -> Int
    inv64 Int
    n))
        | Bool
    otherwise = let nx :: Int
    nx = Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- 64 in Word64 -> Word64 -> Word128
    Word128 (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a0 Int
    nx Word64
    a1 (Int -> Int
    inv64 Int
    nx)) (Word64 -> Int -> Word64 -> Int -> Word64
    comb64 Word64
    a1 Int
    n' Word64
    a0 (Int -> Int
    inv64 Int
    nx))
      where
        n :: Int
        n :: Int
    n | Int
    n' Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    >= 0   = Int
    n' Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `Prelude.mod` 128
          | Bool
    otherwise = 128 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- (Int
    n' Int -> Int -> Int
    forall a. Integral a => a -> a -> a
    `Prelude.mod` 128)

    -- | Bitwise rotate Left
    rotateR :: Word128 -> Int -> Word128
    rotateR :: Word128 -> Int -> Word128
    rotateR w :: Word128
    w n :: Int
    n = Word128 -> Int -> Word128
    rotateL Word128
    w (128 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    n)

    inv64 :: Int -> Int
    inv64 :: Int -> Int
    inv64 i :: Int
    i = 64 Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- Int
    i

    comb64 :: Word64 -> Int -> Word64 -> Int -> Word64
    comb64 :: Word64 -> Int -> Word64 -> Int -> Word64
    comb64 x :: Word64
    x i :: Int
    i y :: Word64
    y j :: Int
    j =
        (Word64
    x Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftL` Int
    i) Word64 -> Word64 -> Word64
    forall a. Bits a => a -> a -> a
    .|. (Word64
    y Word64 -> Int -> Word64
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` Int
    j)

    -- | Test bit
    testBit :: Word128 -> Int -> Bool
    testBit :: Word128 -> Int -> Bool
    testBit (Word128 a1 :: Word64
    a1 a0 :: Word64
    a0) n :: Int
    n
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0 Bool -> Bool -> Bool
    || Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 127 = Bool
    False
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 63           = Word64 -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    Bits.testBit Word64
    a1 (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- 64)
        | Bool
    otherwise        = Word64 -> Int -> Bool
    forall a. Bits a => a -> Int -> Bool
    Bits.testBit Word64
    a0 Int
    n

    -- | bit
    bit :: Int -> Word128
    bit :: Int -> Word128
    bit n :: Int
    n
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    < 0 Bool -> Bool -> Bool
    || Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 127 = Word64 -> Word64 -> Word128
    Word128 0 0
        | Int
    n Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > 63           = Word64 -> Word64 -> Word128
    Word128 (Int -> Word64
    forall a. Bits a => Int -> a
    Bits.bit (Int
    n Int -> Int -> Int
    forall a. Num a => a -> a -> a
    Prelude.- 64)) 0
        | Bool
    otherwise        = Word64 -> Word64 -> Word128
    Word128 0 (Int -> Word64
    forall a. Bits a => Int -> a
    Bits.bit Int
    n)

    literal :: Integer -> Word128
    literal :: Integer -> Word128
    literal i :: Integer
    i = Word64 -> Word64 -> Word128
    Word128
        (Integer -> Word64
    forall a. Num a => Integer -> a
    Prelude.fromInteger (Integer
    i Integer -> Int -> Integer
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` 64))
        (Integer -> Word64
    forall a. Num a => Integer -> a
    Prelude.fromInteger Integer
    i)

    fromNatural :: Natural -> Word128
    fromNatural :: Natural -> Word128
    fromNatural n :: Natural
    n = Word64 -> Word64 -> Word128
    Word128
        (Integer -> Word64
    forall a. Num a => Integer -> a
    Prelude.fromInteger (Natural -> Integer
    naturalToInteger Natural
    n Integer -> Int -> Integer
    forall a. Bits a => a -> Int -> a
    `Bits.unsafeShiftR` 64))
        (Integer -> Word64
    forall a. Num a => Integer -> a
    Prelude.fromInteger (Integer -> Word64) -> Integer -> Word64
    forall a b. (a -> b) -> a -> b
    $ Natural -> Integer
    naturalToInteger Natural
    n)