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

-----------------------------------------------------------------------------
---- |
---- Module      :  Data.WideWord.Int128
----
---- Maintainer  :  erikd@mega-nerd.com
---- Stability   :  experimental
---- Portability :  non-portable (GHC extensions and primops)
----
---- This module provides an opaque signed 128 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^128" result as one would expect from a fixed width unsigned word.
-------------------------------------------------------------------------------

#include <MachDeps.h>

module Data.WideWord.Int128
  ( Int128 (..)
  , byteSwapInt128
  , showHexInt128
  , zeroInt128
  ) 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 Data.WideWord.Word128

import Numeric

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

import GHC.Base (Int (..), and#, int2Word#, minusWord#, not#, or#, plusWord#, plusWord2#
                , subWordC#, timesWord#, timesWord2#, word2Int#, xor#)
import GHC.Enum (predError, succError)
import GHC.Exts ((+#), (*#), State#, Int#, Addr#, ByteArray#, MutableByteArray#)
import GHC.Generics
import GHC.Int (Int64 (..))
import GHC.Real ((%))
import GHC.Word (Word64 (..), Word32, byteSwap64)

#if WORD_SIZE_IN_BITS < 64
import GHC.IntWord64
#endif

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

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

byteSwapInt128 :: Int128 -> Int128
byteSwapInt128 :: Int128 -> Int128
byteSwapInt128 (Int128 Word64
a1 Word64
a0) = Word64 -> Word64 -> Int128
Int128 (Word64 -> Word64
byteSwap64 Word64
a0) (Word64 -> Word64
byteSwap64 Word64
a1)

showHexInt128 :: Int128 -> String
showHexInt128 :: Int128 -> String
showHexInt128 (Int128 Word64
a1 Word64
a0)
  | Word64
a1 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0 = Word64 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a0 String
""
  | Bool
otherwise = Word64 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a1 String
zeros String -> ShowS
forall a. [a] -> [a] -> [a]
++ Word64 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a0 String
""
  where
    h0 :: String
h0 = Word64 -> ShowS
forall a. (Integral a, Show a) => a -> ShowS
showHex Word64
a0 String
""
    zeros :: String
zeros = Int -> Char -> String
forall a. Int -> a -> [a]
replicate (Int
16 Int -> Int -> Int
forall a. Num a => a -> a -> a
- String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
h0) Char
'0'

instance Show Int128 where
  show :: Int128 -> String
show = Integer -> String
forall a. Show a => a -> String
show (Integer -> String) -> (Int128 -> Integer) -> Int128 -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int128 -> Integer
forall a. Integral a => a -> Integer
toInteger

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

instance Ord Int128 where
  compare :: Int128 -> Int128 -> Ordering
compare = Int128 -> Int128 -> Ordering
compare128

instance Bounded Int128 where
  minBound :: Int128
minBound = Word64 -> Word64 -> Int128
Int128 Word64
0x8000000000000000 Word64
0
  maxBound :: Int128
maxBound = Word64 -> Word64 -> Int128
Int128 Word64
0x7fffffffffffffff Word64
forall a. Bounded a => a
maxBound

instance Enum Int128 where
  succ :: Int128 -> Int128
succ = Int128 -> Int128
succ128
  pred :: Int128 -> Int128
pred = Int128 -> Int128
pred128
  toEnum :: Int -> Int128
toEnum = Int -> Int128
toEnum128
  fromEnum :: Int128 -> Int
fromEnum = Int128 -> Int
fromEnum128

instance Num Int128 where
  + :: Int128 -> Int128 -> Int128
(+) = Int128 -> Int128 -> Int128
plus128
  (-) = Int128 -> Int128 -> Int128
minus128
  * :: Int128 -> Int128 -> Int128
(*) = Int128 -> Int128 -> Int128
times128
  negate :: Int128 -> Int128
negate = Int128 -> Int128
negate128
  abs :: Int128 -> Int128
abs = Int128 -> Int128
abs128
  signum :: Int128 -> Int128
signum = Int128 -> Int128
signum128
  fromInteger :: Integer -> Int128
fromInteger = Integer -> Int128
fromInteger128

instance Bits Int128 where
  .&. :: Int128 -> Int128 -> Int128
(.&.) = Int128 -> Int128 -> Int128
and128
  .|. :: Int128 -> Int128 -> Int128
(.|.) = Int128 -> Int128 -> Int128
or128
  xor :: Int128 -> Int128 -> Int128
xor = Int128 -> Int128 -> Int128
xor128
  complement :: Int128 -> Int128
complement = Int128 -> Int128
complement128
  shiftL :: Int128 -> Int -> Int128
shiftL = Int128 -> Int -> Int128
shiftL128
  unsafeShiftL :: Int128 -> Int -> Int128
unsafeShiftL = Int128 -> Int -> Int128
shiftL128
  shiftR :: Int128 -> Int -> Int128
shiftR = Int128 -> Int -> Int128
shiftR128
  unsafeShiftR :: Int128 -> Int -> Int128
unsafeShiftR = Int128 -> Int -> Int128
shiftR128
  rotateL :: Int128 -> Int -> Int128
rotateL = Int128 -> Int -> Int128
rotateL128
  rotateR :: Int128 -> Int -> Int128
rotateR = Int128 -> Int -> Int128
rotateR128

  bitSize :: Int128 -> Int
bitSize Int128
_ = Int
128
  bitSizeMaybe :: Int128 -> Maybe Int
bitSizeMaybe Int128
_ = Int -> Maybe Int
forall a. a -> Maybe a
Just Int
128
  isSigned :: Int128 -> Bool
isSigned Int128
_ = Bool
True

  testBit :: Int128 -> Int -> Bool
testBit = Int128 -> Int -> Bool
testBit128
  bit :: Int -> Int128
bit = Int -> Int128
bit128

  popCount :: Int128 -> Int
popCount = Int128 -> Int
popCount128

instance FiniteBits Int128 where
  finiteBitSize :: Int128 -> Int
finiteBitSize Int128
_ = Int
128
  countLeadingZeros :: Int128 -> Int
countLeadingZeros = Int128 -> Int
countLeadingZeros128
  countTrailingZeros :: Int128 -> Int
countTrailingZeros = Int128 -> Int
countTrailingZeros128

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

instance Integral Int128 where
  quot :: Int128 -> Int128 -> Int128
quot Int128
n Int128
d = (Int128, Int128) -> Int128
forall a b. (a, b) -> a
fst (Int128 -> Int128 -> (Int128, Int128)
quotRem128 Int128
n Int128
d)
  rem :: Int128 -> Int128 -> Int128
rem Int128
n Int128
d = (Int128, Int128) -> Int128
forall a b. (a, b) -> b
snd (Int128 -> Int128 -> (Int128, Int128)
quotRem128 Int128
n Int128
d)
  div :: Int128 -> Int128 -> Int128
div Int128
n Int128
d = (Int128, Int128) -> Int128
forall a b. (a, b) -> a
fst (Int128 -> Int128 -> (Int128, Int128)
divMod128 Int128
n Int128
d)
  mod :: Int128 -> Int128 -> Int128
mod Int128
n Int128
d = (Int128, Int128) -> Int128
forall a b. (a, b) -> b
snd (Int128 -> Int128 -> (Int128, Int128)
divMod128 Int128
n Int128
d)
  quotRem :: Int128 -> Int128 -> (Int128, Int128)
quotRem = Int128 -> Int128 -> (Int128, Int128)
quotRem128
  divMod :: Int128 -> Int128 -> (Int128, Int128)
divMod = Int128 -> Int128 -> (Int128, Int128)
divMod128
  toInteger :: Int128 -> Integer
toInteger = Int128 -> Integer
toInteger128

instance Storable Int128 where
  sizeOf :: Int128 -> Int
sizeOf Int128
i = Int# -> Int
I# (Int128 -> Int#
sizeOf128# Int128
i)
  alignment :: Int128 -> Int
alignment Int128
i = Int# -> Int
I# (Int128 -> Int#
alignment128# Int128
i)
  peek :: Ptr Int128 -> IO Int128
peek = Ptr Int128 -> IO Int128
peek128
  peekElemOff :: Ptr Int128 -> Int -> IO Int128
peekElemOff = Ptr Int128 -> Int -> IO Int128
peekElemOff128
  poke :: Ptr Int128 -> Int128 -> IO ()
poke = Ptr Int128 -> Int128 -> IO ()
poke128
  pokeElemOff :: Ptr Int128 -> Int -> Int128 -> IO ()
pokeElemOff = Ptr Int128 -> Int -> Int128 -> IO ()
pokeElemOff128

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

instance Prim Int128 where
  sizeOf# :: Int128 -> Int#
sizeOf#         = Int128 -> Int#
sizeOf128#
  alignment# :: Int128 -> Int#
alignment#      = Int128 -> Int#
alignment128#
  indexByteArray# :: ByteArray# -> Int# -> Int128
indexByteArray# = ByteArray# -> Int# -> Int128
indexByteArray128#
  readByteArray# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Int128 #)
readByteArray#  = MutableByteArray# s -> Int# -> State# s -> (# State# s, Int128 #)
forall s.
MutableByteArray# s -> Int# -> State# s -> (# State# s, Int128 #)
readByteArray128#
  writeByteArray# :: MutableByteArray# s -> Int# -> Int128 -> State# s -> State# s
writeByteArray# = MutableByteArray# s -> Int# -> Int128 -> State# s -> State# s
forall s.
MutableByteArray# s -> Int# -> Int128 -> State# s -> State# s
writeByteArray128#
  setByteArray# :: MutableByteArray# s
-> Int# -> Int# -> Int128 -> State# s -> State# s
setByteArray#   = MutableByteArray# s
-> Int# -> Int# -> Int128 -> State# s -> State# s
forall s.
MutableByteArray# s
-> Int# -> Int# -> Int128 -> State# s -> State# s
setByteArray128#
  indexOffAddr# :: Addr# -> Int# -> Int128
indexOffAddr#   = Addr# -> Int# -> Int128
indexOffAddr128#
  readOffAddr# :: Addr# -> Int# -> State# s -> (# State# s, Int128 #)
readOffAddr#    = Addr# -> Int# -> State# s -> (# State# s, Int128 #)
forall s. Addr# -> Int# -> State# s -> (# State# s, Int128 #)
readOffAddr128#
  writeOffAddr# :: Addr# -> Int# -> Int128 -> State# s -> State# s
writeOffAddr#   = Addr# -> Int# -> Int128 -> State# s -> State# s
forall s. Addr# -> Int# -> Int128 -> State# s -> State# s
writeOffAddr128#
  setOffAddr# :: Addr# -> Int# -> Int# -> Int128 -> State# s -> State# s
setOffAddr#     = Addr# -> Int# -> Int# -> Int128 -> State# s -> State# s
forall s. Addr# -> Int# -> Int# -> Int128 -> State# s -> State# s
setOffAddr128#
  {-# INLINE sizeOf# #-}
  {-# INLINE alignment# #-}
  {-# INLINE indexByteArray# #-}
  {-# INLINE readByteArray# #-}
  {-# INLINE writeByteArray# #-}
  {-# INLINE setByteArray# #-}
  {-# INLINE indexOffAddr# #-}
  {-# INLINE readOffAddr# #-}
  {-# INLINE writeOffAddr# #-}
  {-# INLINE setOffAddr# #-}

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

{-# RULES
"fromIntegral :: Int128 -> Int128" fromIntegral = id :: Int128 -> Int128
"fromIntegral :: Word128 -> Int128" fromIntegral = \(Word128 a1 a0) -> Int128 a1 a0
"fromIntegral :: Int128 -> Word128" fromIntegral = \(Int128 a1 a0) -> Word128 a1 a0

"fromIntegral :: Word -> Int128"    fromIntegral = Int128 0 . (fromIntegral :: Word -> Word64)
"fromIntegral :: Word32 -> Int128"  fromIntegral = Int128 0 . (fromIntegral :: Word32 -> Word64)
"fromIntegral :: Word64 -> Int128"  fromIntegral = Int128 0
  #-}

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

compare128 :: Int128 -> Int128 -> Ordering
compare128 :: Int128 -> Int128 -> Ordering
compare128 (Int128 Word64
a1 Word64
a0) (Int128 Word64
b1 Word64
b0) =
  Int64 -> Int64 -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Word64 -> Int64
int64OfWord64 Word64
a1) (Word64 -> Int64
int64OfWord64 Word64
b1) Ordering -> Ordering -> Ordering
forall a. Semigroup a => a -> a -> a
<> Word64 -> Word64 -> Ordering
forall a. Ord a => a -> a -> Ordering
compare Word64
a0 Word64
b0
  where
    int64OfWord64 :: Word64 -> Int64
int64OfWord64 (W64# Word#
w) = Int# -> Int64
I64# (Word# -> Int#
word2Int# Word#
w)

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


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


pred128 :: Int128 -> Int128
pred128 :: Int128 -> Int128
pred128 (Int128 Word64
a1 Word64
a0)
  | Word64
a0 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0 = if Word64
a1 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0x8000000000000000
              then String -> Int128
forall a. String -> a
predError String
"Int128"
              else Word64 -> Word64 -> Int128
Int128 (Word64
a1 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
1) Word64
forall a. Bounded a => a
maxBound
  | Bool
otherwise = Word64 -> Word64 -> Int128
Int128 Word64
a1 (Word64
a0 Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
- Word64
1)


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

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

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

{-# INLINABLE plus128 #-}
plus128 :: Int128 -> Int128 -> Int128
plus128 :: Int128 -> Int128 -> Int128
plus128 (Int128 (W64# Word#
a1) (W64# Word#
a0)) (Int128 (W64# Word#
b1) (W64# Word#
b0)) =
  Word64 -> Word64 -> Int128
Int128 (Word# -> Word64
W64# Word#
s1) (Word# -> Word64
W64# Word#
s0)
  where
    !(# Word#
c1, Word#
s0 #) = Word# -> Word# -> (# Word#, Word# #)
plusWord2# Word#
a0 Word#
b0
    s1a :: Word#
s1a = Word# -> Word# -> Word#
plusWord# Word#
a1 Word#
b1
    s1 :: Word#
s1 = Word# -> Word# -> Word#
plusWord# Word#
c1 Word#
s1a

{-# INLINABLE minus128 #-}
minus128 :: Int128 -> Int128 -> Int128
minus128 :: Int128 -> Int128 -> Int128
minus128 (Int128 (W64# Word#
a1) (W64# Word#
a0)) (Int128 (W64# Word#
b1) (W64# Word#
b0)) =
  Word64 -> Word64 -> Int128
Int128 (Word# -> Word64
W64# Word#
d1) (Word# -> Word64
W64# Word#
d0)
  where
    !(# Word#
d0, Int#
c1 #) = Word# -> Word# -> (# Word#, Int# #)
subWordC# Word#
a0 Word#
b0
    a1c :: Word#
a1c = Word# -> Word# -> Word#
minusWord# Word#
a1 (Int# -> Word#
int2Word# Int#
c1)
    d1 :: Word#
d1 = Word# -> Word# -> Word#
minusWord# Word#
a1c Word#
b1

times128 :: Int128 -> Int128 -> Int128
times128 :: Int128 -> Int128 -> Int128
times128 (Int128 (W64# Word#
a1) (W64# Word#
a0)) (Int128 (W64# Word#
b1) (W64# Word#
b0)) =
  Word64 -> Word64 -> Int128
Int128 (Word# -> Word64
W64# Word#
p1) (Word# -> Word64
W64# Word#
p0)
  where
    !(# Word#
c1, Word#
p0 #) = Word# -> Word# -> (# Word#, Word# #)
timesWord2# Word#
a0 Word#
b0
    p1a :: Word#
p1a = Word# -> Word# -> Word#
timesWord# Word#
a1 Word#
b0
    p1b :: Word#
p1b = Word# -> Word# -> Word#
timesWord# Word#
a0 Word#
b1
    p1c :: Word#
p1c = Word# -> Word# -> Word#
plusWord# Word#
p1a Word#
p1b
    p1 :: Word#
p1 = Word# -> Word# -> Word#
plusWord# Word#
p1c Word#
c1

{-# INLINABLE negate128 #-}
negate128 :: Int128 -> Int128
negate128 :: Int128 -> Int128
negate128 (Int128 (W64# Word#
a1) (W64# Word#
a0)) =
  case Word# -> Word# -> (# Word#, Word# #)
plusWord2# (Word# -> Word#
not# Word#
a0) Word#
1## of
    (# Word#
c, Word#
s #) -> Word64 -> Word64 -> Int128
Int128 (Word# -> Word64
W64# (Word# -> Word# -> Word#
plusWord# (Word# -> Word#
not# Word#
a1) Word#
c)) (Word# -> Word64
W64# Word#
s)

{-# INLINABLE abs128 #-}
abs128 :: Int128 -> Int128
abs128 :: Int128 -> Int128
abs128 i :: Int128
i@(Int128 Word64
a1 Word64
_)
  | Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word64
a1 Int
63 = Int128 -> Int128
negate128 Int128
i
  | Bool
otherwise = Int128
i

{-# INLINABLE signum128 #-}
signum128 :: Int128 -> Int128
signum128 :: Int128 -> Int128
signum128 (Int128 Word64
a1 Word64
a0)
  | Word64
a1 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0 Bool -> Bool -> Bool
&& Word64
a0 Word64 -> Word64 -> Bool
forall a. Eq a => a -> a -> Bool
== Word64
0 = Int128
zeroInt128
  | Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word64
a1 Int
63 = Int128
minusOneInt128
  | Bool
otherwise = Int128
oneInt128

{-# INLINABLE complement128 #-}
complement128 :: Int128 -> Int128
complement128 :: Int128 -> Int128
complement128 (Int128 Word64
a1 Word64
a0) = Word64 -> Word64 -> Int128
Int128 (Word64 -> Word64
forall a. Bits a => a -> a
complement Word64
a1) (Word64 -> Word64
forall a. Bits a => a -> a
complement Word64
a0)

fromInteger128 :: Integer -> Int128
fromInteger128 :: Integer -> Int128
fromInteger128 Integer
i =
  Word64 -> Word64 -> Int128
Int128 (Integer -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Integer -> Word64) -> Integer -> Word64
forall a b. (a -> b) -> a -> b
$ Integer
i Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftR` Int
64) (Integer -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral Integer
i)

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

{-# INLINABLE and128 #-}
and128 :: Int128 -> Int128 -> Int128
and128 :: Int128 -> Int128 -> Int128
and128 (Int128 (W64# Word#
a1) (W64# Word#
a0)) (Int128 (W64# Word#
b1) (W64# Word#
b0)) =
  Word64 -> Word64 -> Int128
Int128 (Word# -> Word64
W64# (Word# -> Word# -> Word#
and# Word#
a1 Word#
b1)) (Word# -> Word64
W64# (Word# -> Word# -> Word#
and# Word#
a0 Word#
b0))

{-# INLINABLE or128 #-}
or128 :: Int128 -> Int128 -> Int128
or128 :: Int128 -> Int128 -> Int128
or128 (Int128 (W64# Word#
a1) (W64# Word#
a0)) (Int128 (W64# Word#
b1) (W64# Word#
b0)) =
  Word64 -> Word64 -> Int128
Int128 (Word# -> Word64
W64# (Word# -> Word# -> Word#
or# Word#
a1 Word#
b1)) (Word# -> Word64
W64# (Word# -> Word# -> Word#
or# Word#
a0 Word#
b0))

{-# INLINABLE xor128 #-}
xor128 :: Int128 -> Int128 -> Int128
xor128 :: Int128 -> Int128 -> Int128
xor128 (Int128 (W64# Word#
a1) (W64# Word#
a0)) (Int128 (W64# Word#
b1) (W64# Word#
b0)) =
  Word64 -> Word64 -> Int128
Int128 (Word# -> Word64
W64# (Word# -> Word# -> Word#
xor# Word#
a1 Word#
b1)) (Word# -> Word64
W64# (Word# -> Word# -> Word#
xor# Word#
a0 Word#
b0))

-- Probably not worth inlining this.
shiftL128 :: Int128 -> Int -> Int128
shiftL128 :: Int128 -> Int -> Int128
shiftL128 w :: Int128
w@(Int128 Word64
a1 Word64
a0) Int
s
  | Int
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Int128
w
  | Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Int128 -> Int -> Int128
shiftL128 Int128
w (Int
128 Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Int -> Int
forall a. Num a => a -> a
abs Int
s Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
128))
  | Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
128 = Int128
zeroInt128
  | Int
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 = Word64 -> Word64 -> Int128
Int128 Word64
a0 Word64
0
  | Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
64 = Word64 -> Word64 -> Int128
Int128 (Word64
a0 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` (Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
64)) Word64
0
  | Bool
otherwise =
      Word64 -> Word64 -> Int128
Int128 Word64
s1 Word64
s0
      where
        s0 :: Word64
s0 = Word64
a0 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
s
        s1 :: Word64
s1 = Word64
a1 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
s Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
a0 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` (Int
64 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
s)

-- Probably not worth inlining this.
shiftR128 :: Int128 -> Int -> Int128
shiftR128 :: Int128 -> Int -> Int128
shiftR128 i :: Int128
i@(Int128 Word64
a1 Word64
a0) Int
s
  | Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Int128
zeroInt128
  | Int
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Int128
i
  | Word64 -> Bool
topBitSetWord64 Word64
a1 = Int128 -> Int128
complement128 (Int128 -> Int -> Int128
shiftR128 (Int128 -> Int128
complement128 Int128
i) Int
s)
  | Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
128 = Int128
zeroInt128
  | Int
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 = Word64 -> Word64 -> Int128
Int128 Word64
0 Word64
a1
  | Int
s Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
64 = Word64 -> Word64 -> Int128
Int128 Word64
0 (Word64
a1 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` (Int
s Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
64))
  | Bool
otherwise = Word64 -> Word64 -> Int128
Int128 Word64
s1 Word64
s0
      where
        s1 :: Word64
s1 = Word64
a1 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
s
        s0 :: Word64
s0 = Word64
a0 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
s Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
a1 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` (Int
64 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
s)

rotateL128 :: Int128 -> Int -> Int128
rotateL128 :: Int128 -> Int -> Int128
rotateL128 w :: Int128
w@(Int128 Word64
a1 Word64
a0) Int
r
  | Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Int128
zeroInt128
  | Int
r Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Int128
w
  | Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
128 = Int128 -> Int -> Int128
rotateL128 Int128
w (Int
r Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
128)
  | Int
r Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 = Word64 -> Word64 -> Int128
Int128 Word64
a0 Word64
a1
  | Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
64 = Int128 -> Int -> Int128
rotateL128 (Word64 -> Word64 -> Int128
Int128 Word64
a0 Word64
a1) (Int
r Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
64)
  | Bool
otherwise =
      Word64 -> Word64 -> Int128
Int128 Word64
s1 Word64
s0
      where
        s0 :: Word64
s0 = Word64
a0 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
r Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
a1 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` (Int
64 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
r)
        s1 :: Word64
s1 = Word64
a1 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` Int
r Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
a0 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` (Int
64 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
r)

rotateR128 :: Int128 -> Int -> Int128
rotateR128 :: Int128 -> Int -> Int128
rotateR128 w :: Int128
w@(Int128 Word64
a1 Word64
a0) Int
r
  | Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Int128 -> Int -> Int128
rotateR128 Int128
w (Int
128 Int -> Int -> Int
forall a. Num a => a -> a -> a
- (Int -> Int
forall a. Num a => a -> a
abs Int
r Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
128))
  | Int
r Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
0 = Int128
w
  | Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
128 = Int128 -> Int -> Int128
rotateR128 Int128
w (Int
r Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
128)
  | Int
r Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 = Word64 -> Word64 -> Int128
Int128 Word64
a0 Word64
a1
  | Int
r Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
64 = Int128 -> Int -> Int128
rotateR128 (Word64 -> Word64 -> Int128
Int128 Word64
a0 Word64
a1) (Int
r Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
64)
  | Bool
otherwise =
      Word64 -> Word64 -> Int128
Int128 Word64
s1 Word64
s0
      where
        s0 :: Word64
s0 = Word64
a0 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
r Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
a1 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` (Int
64 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
r)
        s1 :: Word64
s1 = Word64
a1 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftR` Int
r Word64 -> Word64 -> Word64
forall a. Num a => a -> a -> a
+ Word64
a0 Word64 -> Int -> Word64
forall a. Bits a => a -> Int -> a
`shiftL` (Int
64 Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
r)

testBit128 :: Int128 -> Int -> Bool
testBit128 :: Int128 -> Int -> Bool
testBit128 (Int128 Word64
a1 Word64
a0) Int
i
  | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Bool
False
  | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
128 = Bool
False
  | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
64 = Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word64
a1 (Int
i Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
64)
  | Bool
otherwise = Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word64
a0 Int
i

bit128 :: Int -> Int128
bit128 :: Int -> Int128
bit128 Int
indx
  | Int
indx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
0 = Int128
zeroInt128
  | Int
indx Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
128 = Int128
zeroInt128
  | Bool
otherwise = Int128 -> Int -> Int128
shiftL128 Int128
oneInt128 Int
indx

popCount128 :: Int128 -> Int
popCount128 :: Int128 -> Int
popCount128 (Int128 Word64
a1 Word64
a0) = Word64 -> Int
forall a. Bits a => a -> Int
popCount Word64
a1 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word64 -> Int
forall a. Bits a => a -> Int
popCount Word64
a0

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

countLeadingZeros128 :: Int128 -> Int
countLeadingZeros128 :: Int128 -> Int
countLeadingZeros128 (Int128 Word64
a1 Word64
a0) =
  case Word64 -> Int
forall b. FiniteBits b => b -> Int
countLeadingZeros Word64
a1 of
    Int
64 -> Int
64 Int -> Int -> Int
forall a. Num a => a -> a -> a
+  Word64 -> Int
forall b. FiniteBits b => b -> Int
countLeadingZeros Word64
a0
    Int
res -> Int
res

countTrailingZeros128 :: Int128 -> Int
countTrailingZeros128 :: Int128 -> Int
countTrailingZeros128 (Int128 Word64
a1 Word64
a0) =
  case Word64 -> Int
forall b. FiniteBits b => b -> Int
countTrailingZeros Word64
a0 of
    Int
64 -> Int
64 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Word64 -> Int
forall b. FiniteBits b => b -> Int
countTrailingZeros Word64
a1
    Int
res -> Int
res

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

quotRem128 :: Int128 -> Int128 -> (Int128, Int128)
quotRem128 :: Int128 -> Int128 -> (Int128, Int128)
quotRem128 Int128
numer Int128
denom
  | Int128 -> Bool
isNeg Int128
numer Bool -> Bool -> Bool
&& Int128 -> Bool
isNeg Int128
denom = (Word128 -> Int128
word128ToInt128 Word128
wq, Word128 -> Int128
word128ToInt128 (Word128 -> Word128
forall a. Num a => a -> a
negate Word128
wr))
  | Int128 -> Bool
isNeg Int128
numer = (Word128 -> Int128
word128ToInt128 (Word128 -> Word128
forall a. Num a => a -> a
negate Word128
wq), Word128 -> Int128
word128ToInt128 (Word128 -> Word128
forall a. Num a => a -> a
negate Word128
wr))
  | Int128 -> Bool
isNeg Int128
denom = (Word128 -> Int128
word128ToInt128 (Word128 -> Word128
forall a. Num a => a -> a
negate Word128
wq), Word128 -> Int128
word128ToInt128 Word128
wr)
  | Bool
otherwise = (Word128 -> Int128
word128ToInt128 Word128
wq, Word128 -> Int128
word128ToInt128 Word128
wr)
  where
    (Word128
wq, Word128
wr) = Word128 -> Word128 -> (Word128, Word128)
forall a. Integral a => a -> a -> (a, a)
quotRem Word128
absNumerW Word128
absDenomW
    absNumerW :: Word128
absNumerW = Int128 -> Word128
int128ToWord128 (Int128 -> Word128) -> Int128 -> Word128
forall a b. (a -> b) -> a -> b
$ Int128 -> Int128
abs128 Int128
numer
    absDenomW :: Word128
absDenomW = Int128 -> Word128
int128ToWord128 (Int128 -> Word128) -> Int128 -> Word128
forall a b. (a -> b) -> a -> b
$ Int128 -> Int128
abs128 Int128
denom
    isNeg :: Int128 -> Bool
isNeg = Word64 -> Bool
topBitSetWord64 (Word64 -> Bool) -> (Int128 -> Word64) -> Int128 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int128 -> Word64
int128Hi64


divMod128 :: Int128 -> Int128 -> (Int128, Int128)
divMod128 :: Int128 -> Int128 -> (Int128, Int128)
divMod128 Int128
numer Int128
denom
  | Int128 -> Bool
isNeg Int128
numer Bool -> Bool -> Bool
&& Int128 -> Bool
isNeg Int128
denom = (Word128 -> Int128
word128ToInt128 Word128
wq, Word128 -> Int128
word128ToInt128 (Word128 -> Word128
forall a. Num a => a -> a
negate Word128
wr))
  | Int128 -> Bool
isNeg Int128
numer Bool -> Bool -> Bool
&& Word128
wr Word128 -> Word128 -> Bool
forall a. Eq a => a -> a -> Bool
== Word128
0 = (Word128 -> Int128
word128ToInt128 (Word128 -> Word128
forall a. Num a => a -> a
negate Word128
wq), Int128
0)
  | Int128 -> Bool
isNeg Int128
numer = (Word128 -> Int128
word128ToInt128 (Word128 -> Word128
forall a. Num a => a -> a
negate (Word128 -> Word128) -> Word128 -> Word128
forall a b. (a -> b) -> a -> b
$ Word128
wq Word128 -> Word128 -> Word128
forall a. Num a => a -> a -> a
+ Word128
1), Word128 -> Int128
word128ToInt128 (Word128
absDenomW Word128 -> Word128 -> Word128
forall a. Num a => a -> a -> a
- Word128
wr))
  | Int128 -> Bool
isNeg Int128
denom Bool -> Bool -> Bool
&& Word128
wr Word128 -> Word128 -> Bool
forall a. Eq a => a -> a -> Bool
== Word128
0 = (Word128 -> Int128
word128ToInt128 (Word128 -> Word128
forall a. Num a => a -> a
negate Word128
wq), Int128
0)
  | Int128 -> Bool
isNeg Int128
denom = (Word128 -> Int128
word128ToInt128 (Word128 -> Word128
forall a. Num a => a -> a
negate (Word128 -> Word128) -> Word128 -> Word128
forall a b. (a -> b) -> a -> b
$ Word128
wq Word128 -> Word128 -> Word128
forall a. Num a => a -> a -> a
+ Word128
1), Word128 -> Int128
word128ToInt128 (Word128 -> Word128
forall a. Num a => a -> a
negate (Word128 -> Word128) -> Word128 -> Word128
forall a b. (a -> b) -> a -> b
$ Word128
absDenomW Word128 -> Word128 -> Word128
forall a. Num a => a -> a -> a
- Word128
wr))
  | Bool
otherwise = (Word128 -> Int128
word128ToInt128 Word128
wq, Word128 -> Int128
word128ToInt128 Word128
wr)
  where
    (Word128
wq, Word128
wr) = Word128 -> Word128 -> (Word128, Word128)
forall a. Integral a => a -> a -> (a, a)
quotRem Word128
absNumerW Word128
absDenomW
    isNeg :: Int128 -> Bool
isNeg = Word64 -> Bool
topBitSetWord64 (Word64 -> Bool) -> (Int128 -> Word64) -> Int128 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int128 -> Word64
int128Hi64
    absNumerW :: Word128
absNumerW = Int128 -> Word128
int128ToWord128 (Int128 -> Word128) -> Int128 -> Word128
forall a b. (a -> b) -> a -> b
$ Int128 -> Int128
abs128 Int128
numer
    absDenomW :: Word128
absDenomW = Int128 -> Word128
int128ToWord128 (Int128 -> Word128) -> Int128 -> Word128
forall a b. (a -> b) -> a -> b
$ Int128 -> Int128
abs128 Int128
denom


toInteger128 :: Int128 -> Integer
toInteger128 :: Int128 -> Integer
toInteger128 i :: Int128
i@(Int128 Word64
a1 Word64
a0)
  | Word64 -> Int
forall a. Bits a => a -> Int
popCount Word64
a1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 Bool -> Bool -> Bool
&& Word64 -> Int
forall a. Bits a => a -> Int
popCount Word64
a0 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
64 = -Integer
1
  | Bool -> Bool
not (Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word64
a1 Int
63) = Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
a1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
64 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
a0
  | Bool
otherwise =
      case Int128 -> Int128
negate128 Int128
i of
        Int128 Word64
n1 Word64
n0 -> Integer -> Integer
forall a. Num a => a -> a
negate (Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n1 Integer -> Int -> Integer
forall a. Bits a => a -> Int -> a
`shiftL` Int
64 Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Word64 -> Integer
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
n0)

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

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

peekElemOff128 :: Ptr Int128 -> Int -> IO Int128
peekElemOff128 :: Ptr Int128 -> Int -> IO Int128
peekElemOff128 Ptr Int128
ptr Int
idx =
  Word64 -> Word64 -> Int128
Int128 (Word64 -> Word64 -> Int128) -> IO Word64 -> IO (Word64 -> Int128)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr Word64 -> Int -> IO Word64
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff (Ptr Int128 -> Ptr Word64
forall a b. Ptr a -> Ptr b
castPtr Ptr Int128
ptr) (Int
idx2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
index1)
            IO (Word64 -> Int128) -> IO Word64 -> IO Int128
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Ptr Word64 -> Int -> IO Word64
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff (Ptr Int128 -> Ptr Word64
forall a b. Ptr a -> Ptr b
castPtr Ptr Int128
ptr) (Int
idx2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
index0)
  where idx2 :: Int
idx2 = Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
idx

poke128 :: Ptr Int128 -> Int128 -> IO ()
poke128 :: Ptr Int128 -> Int128 -> IO ()
poke128 Ptr Int128
ptr (Int128 Word64
a1 Word64
a0) =
  Ptr Word64 -> Int -> Word64 -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (Ptr Int128 -> Ptr Word64
forall a b. Ptr a -> Ptr b
castPtr Ptr Int128
ptr) Int
index1 Word64
a1 IO () -> IO () -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Ptr Word64 -> Int -> Word64 -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (Ptr Int128 -> Ptr Word64
forall a b. Ptr a -> Ptr b
castPtr Ptr Int128
ptr) Int
index0 Word64
a0

pokeElemOff128 :: Ptr Int128 -> Int -> Int128 -> IO ()
pokeElemOff128 :: Ptr Int128 -> Int -> Int128 -> IO ()
pokeElemOff128 Ptr Int128
ptr Int
idx (Int128 Word64
a1 Word64
a0) = do
  let idx2 :: Int
idx2 = Int
2 Int -> Int -> Int
forall a. Num a => a -> a -> a
* Int
idx
  Ptr Word64 -> Int -> Word64 -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (Ptr Int128 -> Ptr Word64
forall a b. Ptr a -> Ptr b
castPtr Ptr Int128
ptr) (Int
idx2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
index0) Word64
a0
  Ptr Word64 -> Int -> Word64 -> IO ()
forall a. Storable a => Ptr a -> Int -> a -> IO ()
pokeElemOff (Ptr Int128 -> Ptr Word64
forall a b. Ptr a -> Ptr b
castPtr Ptr Int128
ptr) (Int
idx2 Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
index1) Word64
a1

-- -----------------------------------------------------------------------------
-- Helpers.

{-# INLINE int128ToWord128 #-}
int128ToWord128 :: Int128 -> Word128
int128ToWord128 :: Int128 -> Word128
int128ToWord128 (Int128 Word64
a1 Word64
a0) = Word64 -> Word64 -> Word128
Word128 Word64
a1 Word64
a0

{-# INLINE topBitSetWord64 #-}
topBitSetWord64 :: Word64 -> Bool
topBitSetWord64 :: Word64 -> Bool
topBitSetWord64 Word64
w = Word64 -> Int -> Bool
forall a. Bits a => a -> Int -> Bool
testBit Word64
w Int
63

{-# INLINE word128ToInt128 #-}
word128ToInt128 :: Word128 -> Int128
word128ToInt128 :: Word128 -> Int128
word128ToInt128 (Word128 Word64
a1 Word64
a0) = Word64 -> Word64 -> Int128
Int128 Word64
a1 Word64
a0

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

{-# INLINE sizeOf128# #-}
sizeOf128# :: Int128 -> Int#
sizeOf128# :: Int128 -> Int#
sizeOf128# Int128
_ = Int#
2# Int# -> Int# -> Int#
*# Word64 -> Int#
forall a. Prim a => a -> Int#
sizeOf# (Word64
forall a. HasCallStack => a
undefined :: Word64)

{-# INLINE alignment128# #-}
alignment128# :: Int128 -> Int#
alignment128# :: Int128 -> Int#
alignment128# Int128
_ = Int#
2# Int# -> Int# -> Int#
*# Word64 -> Int#
forall a. Prim a => a -> Int#
alignment# (Word64
forall a. HasCallStack => a
undefined :: Word64)

{-# INLINE indexByteArray128# #-}
indexByteArray128# :: ByteArray# -> Int# -> Int128
indexByteArray128# :: ByteArray# -> Int# -> Int128
indexByteArray128# ByteArray#
arr# Int#
i# =
  let i2# :: Int#
i2# = Int#
2# Int# -> Int# -> Int#
*# Int#
i#
      x :: Word64
x = ByteArray# -> Int# -> Word64
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index1)
      y :: Word64
y = ByteArray# -> Int# -> Word64
forall a. Prim a => ByteArray# -> Int# -> a
indexByteArray# ByteArray#
arr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index0)
  in Word64 -> Word64 -> Int128
Int128 Word64
x Word64
y

{-# INLINE readByteArray128# #-}
readByteArray128# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Int128 #)
readByteArray128# :: MutableByteArray# s -> Int# -> State# s -> (# State# s, Int128 #)
readByteArray128# MutableByteArray# s
arr# Int#
i# =
  \State# s
s0 -> case MutableByteArray# s -> Int# -> State# s -> (# State# s, Word64 #)
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
s0 of
    (# State# s
s1, Word64
x #) -> case MutableByteArray# s -> Int# -> State# s -> (# State# s, Word64 #)
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
s1 of
      (# State# s
s2, Word64
y #) -> (# State# s
s2, Word64 -> Word64 -> Int128
Int128 Word64
x Word64
y #)
  where i2# :: Int#
i2# = Int#
2# Int# -> Int# -> Int#
*# Int#
i#

{-# INLINE writeByteArray128# #-}
writeByteArray128# :: MutableByteArray# s -> Int# -> Int128 -> State# s -> State# s
writeByteArray128# :: MutableByteArray# s -> Int# -> Int128 -> State# s -> State# s
writeByteArray128# MutableByteArray# s
arr# Int#
i# (Int128 Word64
a Word64
b) =
  \State# s
s0 -> case MutableByteArray# s -> Int# -> Word64 -> State# s -> State# s
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
a State# s
s0 of
    State# s
s1 -> case MutableByteArray# s -> Int# -> Word64 -> State# s -> State# s
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
b State# s
s1 of
      State# s
s2 -> State# s
s2
  where i2# :: Int#
i2# = Int#
2# Int# -> Int# -> Int#
*# Int#
i#

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

{-# INLINE indexOffAddr128# #-}
indexOffAddr128# :: Addr# -> Int# -> Int128
indexOffAddr128# :: Addr# -> Int# -> Int128
indexOffAddr128# Addr#
addr# Int#
i# =
  let i2# :: Int#
i2# = Int#
2# Int# -> Int# -> Int#
*# Int#
i#
      x :: Word64
x = Addr# -> Int# -> Word64
forall a. Prim a => Addr# -> Int# -> a
indexOffAddr# Addr#
addr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index1)
      y :: Word64
y = Addr# -> Int# -> Word64
forall a. Prim a => Addr# -> Int# -> a
indexOffAddr# Addr#
addr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index0)
  in Word64 -> Word64 -> Int128
Int128 Word64
x Word64
y

{-# INLINE readOffAddr128# #-}
readOffAddr128# :: Addr# -> Int# -> State# s -> (# State# s, Int128 #)
readOffAddr128# :: Addr# -> Int# -> State# s -> (# State# s, Int128 #)
readOffAddr128# Addr#
addr# Int#
i# =
  \State# s
s0 -> case Addr# -> Int# -> State# s -> (# State# s, Word64 #)
forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
addr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index1) State# s
s0 of
    (# State# s
s1, Word64
x #) -> case Addr# -> Int# -> State# s -> (# State# s, Word64 #)
forall a s.
Prim a =>
Addr# -> Int# -> State# s -> (# State# s, a #)
readOffAddr# Addr#
addr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index0) State# s
s1 of
      (# State# s
s2, Word64
y #) -> (# State# s
s2, Word64 -> Word64 -> Int128
Int128 Word64
x Word64
y #)
  where i2# :: Int#
i2# = Int#
2# Int# -> Int# -> Int#
*# Int#
i#

{-# INLINE writeOffAddr128# #-}
writeOffAddr128# :: Addr# -> Int# -> Int128 -> State# s -> State# s
writeOffAddr128# :: Addr# -> Int# -> Int128 -> State# s -> State# s
writeOffAddr128# Addr#
addr# Int#
i# (Int128 Word64
a Word64
b) =
  \State# s
s0 -> case Addr# -> Int# -> Word64 -> State# s -> State# s
forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
addr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index1) Word64
a State# s
s0 of
    State# s
s1 -> case Addr# -> Int# -> Word64 -> State# s -> State# s
forall a s. Prim a => Addr# -> Int# -> a -> State# s -> State# s
writeOffAddr# Addr#
addr# (Int#
i2# Int# -> Int# -> Int#
+# Int -> Int#
unInt Int
index0) Word64
b State# s
s1 of
      State# s
s2 -> State# s
s2
  where i2# :: Int#
i2# = Int#
2# Int# -> Int# -> Int#
*# Int#
i#

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

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

zeroInt128 :: Int128
zeroInt128 :: Int128
zeroInt128 = Word64 -> Word64 -> Int128
Int128 Word64
0 Word64
0

oneInt128 :: Int128
oneInt128 :: Int128
oneInt128 = Word64 -> Word64 -> Int128
Int128 Word64
0 Word64
1

minusOneInt128 :: Int128
minusOneInt128 :: Int128
minusOneInt128 = Word64 -> Word64 -> Int128
Int128 Word64
forall a. Bounded a => a
maxBound Word64
forall a. Bounded a => a
maxBound

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

index0, index1 :: Int
#if WORDS_BIGENDIAN
index0 = 1
index1 = 0
#else
index0 :: Int
index0 = Int
0
index1 :: Int
index1 = Int
1
#endif