#include "MachDeps.h"
module GHC.Integer.GMP.Internals
(
Integer (S#,Jn#,Jp#)
, isValidInteger#
, module GHC.Integer
, gcdInteger
, gcdExtInteger
, lcmInteger
, sqrInteger
, powModInteger
, recipModInteger
, wordToNegInteger
, bigNatToInteger
, bigNatToNegInteger
, BigNat(..)
, GmpLimb, GmpLimb#
, GmpSize, GmpSize#
, isValidBigNat#
, sizeofBigNat#
, zeroBigNat
, oneBigNat
, byteArrayToBigNat#
, wordToBigNat
, wordToBigNat2
, bigNatToInt
, bigNatToWord
, indexBigNat#
, plusBigNat
, plusBigNatWord
, minusBigNat
, minusBigNatWord
, timesBigNat
, timesBigNatWord
, sqrBigNat
, quotRemBigNat
, quotRemBigNatWord
, quotBigNatWord
, quotBigNat
, remBigNat
, remBigNatWord
, gcdBigNat
, gcdBigNatWord
, shiftRBigNat
, shiftLBigNat
, testBitBigNat
, clearBitBigNat
, complementBitBigNat
, setBitBigNat
, andBigNat
, xorBigNat
, popCountBigNat
, orBigNat
, bitBigNat
, isZeroBigNat
, compareBigNatWord
, compareBigNat
, eqBigNatWord
, eqBigNatWord#
, eqBigNat
, eqBigNat#
, gtBigNatWord#
, sizeInBaseBigNat
, sizeInBaseInteger
, sizeInBaseWord#
, exportBigNatToAddr
, exportIntegerToAddr
, exportBigNatToMutableByteArray
, exportIntegerToMutableByteArray
, importBigNatFromAddr
, importIntegerFromAddr
, importBigNatFromByteArray
, importIntegerFromByteArray
) where
import GHC.Integer
import GHC.Natural
import GHC.Num.Integer (Integer(..))
import qualified GHC.Num.Integer as I
import qualified GHC.Num.BigNat as B
import qualified GHC.Num.Primitives as P
import GHC.Types
import GHC.Prim
import GHC.Exts (runRW#)
import Control.Exception
pattern S# :: Int# -> Integer
pattern S# i = IS i
fromBN# :: BigNat -> ByteArray#
fromBN# (BN# x) = x
fromIP :: Integer -> (# () | BigNat #)
fromIP (IP x) = (# | BN# x #)
fromIP _ = (# () | #)
fromIN :: Integer -> (# () | BigNat #)
fromIN (IN x) = (# | BN# x #)
fromIN _ = (# () | #)
pattern Jp# :: BigNat -> Integer
pattern Jp# i <- (fromIP -> (# | i #))
where
Jp# i = IP (fromBN# i)
pattern Jn# :: BigNat -> Integer
pattern Jn# i <- (fromIN -> (# | i #))
where
Jn# i = IN (fromBN# i)
isValidInteger# :: Integer -> Int#
isValidInteger# = I.integerCheck#
gcdInteger :: Integer -> Integer -> Integer
gcdInteger = I.integerGcd
gcdExtInteger :: Integer -> Integer -> (# Integer, Integer #)
gcdExtInteger a b = case I.integerGcde# a b of
(# g, s, _t #) -> (# g, s #)
lcmInteger :: Integer -> Integer -> Integer
lcmInteger = I.integerLcm
sqrInteger :: Integer -> Integer
sqrInteger = I.integerSqr
recipModInteger :: Integer -> Integer -> Integer
recipModInteger x m = case I.integerRecipMod# x (I.integerToNatural m) of
(# y | #) -> I.integerFromNatural y
(# | () #) -> 0
powModInteger :: Integer -> Integer -> Integer -> Integer
powModInteger b e m = case I.integerPowMod# b e (I.integerToNatural m) of
(# r | #) -> I.integerFromNatural r
(# | () #) -> 0
wordToNegInteger :: Word# -> Integer
wordToNegInteger = I.integerFromWordNeg#
bigNatToInteger :: BigNat -> Integer
bigNatToInteger (BN# i) = I.integerFromBigNat# i
bigNatToNegInteger :: BigNat -> Integer
bigNatToNegInteger (BN# i) = I.integerFromBigNatNeg# i
type GmpLimb = Word
type GmpLimb# = Word#
type GmpSize = Int
type GmpSize# = Int#
sizeofBigNat# :: BigNat -> GmpSize#
sizeofBigNat# (BN# i) = B.bigNatSize# i
isValidBigNat# :: BigNat -> Int#
isValidBigNat# (BN# i) = B.bigNatCheck# i
zeroBigNat :: BigNat
zeroBigNat = B.bigNatZero
oneBigNat :: BigNat
oneBigNat = B.bigNatOne
plusBigNat :: BigNat -> BigNat -> BigNat
plusBigNat (BN# a) (BN# b) = BN# (B.bigNatAdd a b)
plusBigNatWord :: BigNat -> GmpLimb# -> BigNat
plusBigNatWord (BN# a) w = BN# (B.bigNatAddWord# a w)
minusBigNat :: BigNat -> BigNat -> BigNat
minusBigNat (BN# a) (BN# b) = case B.bigNatSub a b of
(# () | #) -> throw Underflow
(# | r #) -> BN# r
minusBigNatWord :: BigNat -> GmpLimb# -> BigNat
minusBigNatWord (BN# a) b = case B.bigNatSubWord# a b of
(# () | #) -> throw Underflow
(# | r #) -> BN# r
timesBigNat :: BigNat -> BigNat -> BigNat
timesBigNat (BN# a) (BN# b) = BN# (B.bigNatMul a b)
timesBigNatWord :: BigNat -> GmpLimb# -> BigNat
timesBigNatWord (BN# a) w = BN# (B.bigNatMulWord# a w)
sqrBigNat :: BigNat -> BigNat
sqrBigNat (BN# a) = BN# (B.bigNatSqr a)
quotRemBigNat :: BigNat -> BigNat -> (# BigNat,BigNat #)
quotRemBigNat (BN# a) (BN# b) = case B.bigNatQuotRem# a b of
(# q, r #) -> (# BN# q, BN# r #)
quotRemBigNatWord :: BigNat -> GmpLimb# -> (# BigNat, GmpLimb# #)
quotRemBigNatWord (BN# a) b = case B.bigNatQuotRemWord# a b of
(# q, r #) -> (# BN# q, r #)
quotBigNat :: BigNat -> BigNat -> BigNat
quotBigNat (BN# a) (BN# b) = BN# (B.bigNatQuot a b)
quotBigNatWord :: BigNat -> GmpLimb# -> BigNat
quotBigNatWord (BN# a) b = BN# (B.bigNatQuotWord# a b)
remBigNat :: BigNat -> BigNat -> BigNat
remBigNat (BN# a) (BN# b) = BN# (B.bigNatRem a b)
remBigNatWord :: BigNat -> GmpLimb# -> Word#
remBigNatWord (BN# a) b = B.bigNatRemWord# a b
gcdBigNatWord :: BigNat -> Word# -> Word#
gcdBigNatWord (BN# a) b = B.bigNatGcdWord# a b
gcdBigNat:: BigNat -> BigNat -> BigNat
gcdBigNat (BN# a) (BN# b) = BN# (B.bigNatGcd a b)
shiftRBigNat :: BigNat -> Int# -> BigNat
shiftRBigNat (BN# a) i = BN# (B.bigNatShiftR# a (int2Word# i))
shiftLBigNat :: BigNat -> Int# -> BigNat
shiftLBigNat (BN# a) i = BN# (B.bigNatShiftL# a (int2Word# i))
testBitBigNat :: BigNat -> Int# -> Bool
testBitBigNat (BN# a) i = isTrue# (B.bigNatTestBit# a (int2Word# i))
clearBitBigNat :: BigNat -> Int# -> BigNat
clearBitBigNat (BN# a) i = BN# (B.bigNatClearBit# a (int2Word# i))
complementBitBigNat :: BigNat -> Int# -> BigNat
complementBitBigNat (BN# a) i = BN# (B.bigNatComplementBit# a (int2Word# i))
setBitBigNat :: BigNat -> Int# -> BigNat
setBitBigNat (BN# a) i = BN# (B.bigNatSetBit# a (int2Word# i))
andBigNat :: BigNat -> BigNat -> BigNat
andBigNat (BN# a) (BN# b) = BN# (B.bigNatAnd a b)
orBigNat :: BigNat -> BigNat -> BigNat
orBigNat (BN# a) (BN# b) = BN# (B.bigNatOr a b)
xorBigNat :: BigNat -> BigNat -> BigNat
xorBigNat (BN# a) (BN# b) = BN# (B.bigNatXor a b)
popCountBigNat :: BigNat -> Int#
popCountBigNat (BN# a) = word2Int# (B.bigNatPopCount# a)
bitBigNat :: Int# -> BigNat
bitBigNat i = BN# (B.bigNatBit# (int2Word# i))
isZeroBigNat :: BigNat -> Bool
isZeroBigNat (BN# a) = B.bigNatIsZero a
compareBigNat :: BigNat -> BigNat -> Ordering
compareBigNat (BN# a) (BN# b) = B.bigNatCompare a b
compareBigNatWord :: BigNat -> GmpLimb# -> Ordering
compareBigNatWord (BN# a) w = B.bigNatCompareWord# a w
eqBigNatWord :: BigNat -> GmpLimb# -> Bool
eqBigNatWord (BN# a) w = isTrue# (B.bigNatEqWord# a w)
eqBigNatWord# :: BigNat -> GmpLimb# -> Int#
eqBigNatWord# (BN# a) w = B.bigNatEqWord# a w
eqBigNat# :: BigNat -> BigNat -> Int#
eqBigNat# (BN# a) (BN# b) = B.bigNatEq# a b
eqBigNat :: BigNat -> BigNat -> Bool
eqBigNat (BN# a) (BN# b) = B.bigNatEq a b
gtBigNatWord# :: BigNat -> GmpLimb# -> Int#
gtBigNatWord# (BN# a) w = B.bigNatGtWord# a w
sizeInBaseBigNat :: BigNat -> Int# -> Word#
sizeInBaseBigNat (BN# a) b = B.bigNatSizeInBase# (int2Word# b) a
sizeInBaseInteger :: Integer -> Int# -> Word#
sizeInBaseInteger i b = I.integerSizeInBase# (int2Word# b) i
sizeInBaseWord# :: Word# -> Int# -> Word#
sizeInBaseWord# a b = P.wordSizeInBase# (int2Word# b) a
importBigNatFromAddr :: Addr# -> Word# -> Int# -> IO BigNat
importBigNatFromAddr addr sz endian = IO \s ->
case B.bigNatFromAddr# sz addr endian s of
(# s', b #) -> (# s', BN# b #)
exportBigNatToAddr :: BigNat -> Addr# -> Int# -> IO Word
exportBigNatToAddr (BN# b) addr endian = IO \s ->
case B.bigNatToAddr# b addr endian s of
(# s', w #) -> (# s', W# w #)
importIntegerFromAddr :: Addr# -> Word# -> Int# -> IO Integer
importIntegerFromAddr addr sz endian = IO \s ->
case I.integerFromAddr# sz addr endian s of
(# s', i #) -> (# s', i #)
exportIntegerToAddr :: Integer -> Addr# -> Int# -> IO Word
exportIntegerToAddr i addr endian = IO \s ->
case I.integerToAddr# i addr endian s of
(# s', w #) -> (# s', W# w #)
wordToBigNat :: Word# -> BigNat
wordToBigNat w = BN# (B.bigNatFromWord# w)
wordToBigNat2 :: Word# -> Word# -> BigNat
wordToBigNat2 h l = BN# (B.bigNatFromWord2# h l)
bigNatToInt :: BigNat -> Int#
bigNatToInt (BN# b) = B.bigNatToInt# b
bigNatToWord :: BigNat -> Word#
bigNatToWord (BN# b) = B.bigNatToWord# b
indexBigNat# :: BigNat -> GmpSize# -> GmpLimb#
indexBigNat# (BN# b) i = B.bigNatIndex# b i
importBigNatFromByteArray :: ByteArray# -> Word# -> Word# -> Int# -> BigNat
importBigNatFromByteArray ba off sz endian = case runRW# (B.bigNatFromByteArray# sz ba off endian) of
(# _, r #) -> BN# r
exportBigNatToMutableByteArray :: BigNat -> MutableByteArray# RealWorld -> Word# -> Int# -> IO Word
exportBigNatToMutableByteArray (BN# ba) mba off endian = IO (\s -> case B.bigNatToMutableByteArray# ba mba off endian s of
(# s', r #) -> (# s', W# r #))
importIntegerFromByteArray :: ByteArray# -> Word# -> Word# -> Int# -> Integer
importIntegerFromByteArray ba off sz endian = case runRW# (I.integerFromByteArray# sz ba off endian) of
(# _, r #) -> r
exportIntegerToMutableByteArray :: Integer -> MutableByteArray# RealWorld -> Word# -> Int# -> IO Word
exportIntegerToMutableByteArray i mba off endian = IO (\s -> case I.integerToMutableByteArray# i mba off endian s of
(# s', r #) -> (# s', W# r #))
byteArrayToBigNat# :: ByteArray# -> GmpSize# -> BigNat
byteArrayToBigNat# ba n = B.bigNatFromWordArray ba (int2Word# n)