    {-# LANGUAGE CPP #-}
    {-# LANGUAGE MagicHash #-}
    {-# LANGUAGE UnboxedTuples #-}
    {-# LANGUAGE NoImplicitPrelude #-}

    {-# OPTIONS_HADDOCK not-home #-}

    #include "MachDeps.h"

    -- | Compatibility module for pre ghc-bignum code.
    module GHC.Integer (
        Integer,

        -- * Construct 'Integer's
        smallInteger, wordToInteger,
    #if WORD_SIZE_IN_BITS < 64
        word64ToInteger, int64ToInteger,
    #endif
        -- * Conversion to other integral types
        integerToWord, integerToInt,
    #if WORD_SIZE_IN_BITS < 64
        integerToWord64, integerToInt64,
    #endif

        -- * Helpers for 'RealFloat' type-class operations
        encodeFloatInteger, floatFromInteger,
        encodeDoubleInteger, decodeDoubleInteger, doubleFromInteger,

        -- * Arithmetic operations
        plusInteger, minusInteger, timesInteger, negateInteger,
        absInteger, signumInteger,

        divModInteger, divInteger, modInteger,
        quotRemInteger, quotInteger, remInteger,

        -- * Comparison predicates
        eqInteger,  neqInteger,  leInteger,  gtInteger,  ltInteger,  geInteger,
        compareInteger,

        -- ** 'Int#'-boolean valued versions of comparison predicates
        --
        -- | These operations return @0#@ and @1#@ instead of 'False' and
        -- 'True' respectively.  See
        -- <https://gitlab.haskell.org/ghc/ghc/wikis/prim-bool PrimBool wiki-page>
        -- for more details
        eqInteger#, neqInteger#, leInteger#, gtInteger#, ltInteger#, geInteger#,

        -- * Bit-operations
        andInteger, orInteger, xorInteger,

        complementInteger,
        shiftLInteger, shiftRInteger, testBitInteger,

        popCountInteger, bitInteger,

        -- * Hashing
        hashInteger,
        ) where

    import GHC.Num.Integer (Integer)
    import qualified GHC.Num.Integer as I
    import GHC.Prim
    import GHC.Types

    smallInteger :: Int# -> Integer
    smallInteger :: Int# -> Integer
    smallInteger = Int# -> Integer
    I.integerFromInt#

    integerToInt :: Integer -> Int#
    integerToInt :: Integer -> Int#
    integerToInt = Integer -> Int#
    I.integerToInt#

    wordToInteger :: Word# -> Integer
    wordToInteger :: Word# -> Integer
    wordToInteger = Word# -> Integer
    I.integerFromWord#

    integerToWord :: Integer -> Word#
    integerToWord :: Integer -> Word#
    integerToWord = Integer -> Word#
    I.integerToWord#

    #if WORD_SIZE_IN_BITS < 64

    word64ToInteger :: Word64# -> Integer
    word64ToInteger = I.integerFromWord64#

    integerToWord64 :: Integer -> Word64#
    integerToWord64 = I.integerToWord64#

    int64ToInteger :: Int64# -> Integer
    int64ToInteger = I.integerFromInt64#

    integerToInt64 :: Integer -> Int64#
    integerToInt64 = I.integerToInt64#

    #endif

    encodeFloatInteger :: Integer -> Int# -> Float#
    encodeFloatInteger :: Integer -> Int# -> Float#
    encodeFloatInteger = Integer -> Int# -> Float#
    I.integerEncodeFloat#

    floatFromInteger :: Integer -> Float#
    floatFromInteger :: Integer -> Float#
    floatFromInteger = Integer -> Float#
    I.integerToFloat#

    encodeDoubleInteger :: Integer -> Int# -> Double#
    encodeDoubleInteger :: Integer -> Int# -> Double#
    encodeDoubleInteger = Integer -> Int# -> Double#
    I.integerEncodeDouble#

    doubleFromInteger :: Integer -> Double#
    doubleFromInteger :: Integer -> Double#
    doubleFromInteger = Integer -> Double#
    I.integerToDouble#

    decodeDoubleInteger :: Double# -> (# Integer, Int# #)
    decodeDoubleInteger :: Double# -> (# Integer, Int# #)
    decodeDoubleInteger = Double# -> (# Integer, Int# #)
    I.integerDecodeDouble#

    plusInteger :: Integer -> Integer -> Integer
    plusInteger :: Integer -> Integer -> Integer
    plusInteger = Integer -> Integer -> Integer
    I.integerAdd

    minusInteger :: Integer -> Integer -> Integer
    minusInteger :: Integer -> Integer -> Integer
    minusInteger = Integer -> Integer -> Integer
    I.integerSub

    timesInteger :: Integer -> Integer -> Integer
    timesInteger :: Integer -> Integer -> Integer
    timesInteger = Integer -> Integer -> Integer
    I.integerMul

    negateInteger :: Integer -> Integer
    negateInteger :: Integer -> Integer
    negateInteger = Integer -> Integer
    I.integerNegate

    absInteger :: Integer -> Integer
    absInteger :: Integer -> Integer
    absInteger = Integer -> Integer
    I.integerAbs

    signumInteger :: Integer -> Integer
    signumInteger :: Integer -> Integer
    signumInteger = Integer -> Integer
    I.integerSignum

    divModInteger :: Integer -> Integer -> (# Integer, Integer #)
    divModInteger :: Integer -> Integer -> (# Integer, Integer #)
    divModInteger = Integer -> Integer -> (# Integer, Integer #)
    I.integerDivMod#

    divInteger :: Integer -> Integer -> Integer
    divInteger :: Integer -> Integer -> Integer
    divInteger = Integer -> Integer -> Integer
    I.integerDiv

    modInteger :: Integer -> Integer -> Integer
    modInteger :: Integer -> Integer -> Integer
    modInteger = Integer -> Integer -> Integer
    I.integerMod

    quotRemInteger :: Integer -> Integer -> (# Integer, Integer #)
    quotRemInteger :: Integer -> Integer -> (# Integer, Integer #)
    quotRemInteger = Integer -> Integer -> (# Integer, Integer #)
    I.integerQuotRem#

    quotInteger :: Integer -> Integer -> Integer
    quotInteger :: Integer -> Integer -> Integer
    quotInteger = Integer -> Integer -> Integer
    I.integerQuot

    remInteger :: Integer -> Integer -> Integer
    remInteger :: Integer -> Integer -> Integer
    remInteger = Integer -> Integer -> Integer
    I.integerRem

    eqInteger :: Integer -> Integer -> Bool
    eqInteger :: Integer -> Integer -> Bool
    eqInteger = Integer -> Integer -> Bool
    I.integerEq

    neqInteger :: Integer -> Integer -> Bool
    neqInteger :: Integer -> Integer -> Bool
    neqInteger = Integer -> Integer -> Bool
    I.integerNe

    leInteger :: Integer -> Integer -> Bool
    leInteger :: Integer -> Integer -> Bool
    leInteger = Integer -> Integer -> Bool
    I.integerLe

    gtInteger :: Integer -> Integer -> Bool
    gtInteger :: Integer -> Integer -> Bool
    gtInteger = Integer -> Integer -> Bool
    I.integerGt

    ltInteger :: Integer -> Integer -> Bool
    ltInteger :: Integer -> Integer -> Bool
    ltInteger = Integer -> Integer -> Bool
    I.integerLt

    geInteger :: Integer -> Integer -> Bool
    geInteger :: Integer -> Integer -> Bool
    geInteger = Integer -> Integer -> Bool
    I.integerGe

    compareInteger :: Integer -> Integer -> Ordering
    compareInteger :: Integer -> Integer -> Ordering
    compareInteger = Integer -> Integer -> Ordering
    I.integerCompare

    eqInteger# :: Integer -> Integer -> Int#
    eqInteger# :: Integer -> Integer -> Int#
    eqInteger# = Integer -> Integer -> Int#
    I.integerEq#

    neqInteger# :: Integer -> Integer -> Int#
    neqInteger# :: Integer -> Integer -> Int#
    neqInteger# = Integer -> Integer -> Int#
    I.integerNe#

    leInteger# :: Integer -> Integer -> Int#
    leInteger# :: Integer -> Integer -> Int#
    leInteger# = Integer -> Integer -> Int#
    I.integerLe#

    gtInteger# :: Integer -> Integer -> Int#
    gtInteger# :: Integer -> Integer -> Int#
    gtInteger# = Integer -> Integer -> Int#
    I.integerGt#

    ltInteger# :: Integer -> Integer -> Int#
    ltInteger# :: Integer -> Integer -> Int#
    ltInteger# = Integer -> Integer -> Int#
    I.integerLt#

    geInteger# :: Integer -> Integer -> Int#
    geInteger# :: Integer -> Integer -> Int#
    geInteger# = Integer -> Integer -> Int#
    I.integerGe#

    andInteger :: Integer -> Integer -> Integer
    andInteger :: Integer -> Integer -> Integer
    andInteger = Integer -> Integer -> Integer
    I.integerAnd

    orInteger :: Integer -> Integer -> Integer
    orInteger :: Integer -> Integer -> Integer
    orInteger = Integer -> Integer -> Integer
    I.integerOr

    xorInteger :: Integer -> Integer -> Integer
    xorInteger :: Integer -> Integer -> Integer
    xorInteger = Integer -> Integer -> Integer
    I.integerXor

    complementInteger :: Integer -> Integer
    complementInteger :: Integer -> Integer
    complementInteger = Integer -> Integer
    I.integerComplement

    shiftLInteger :: Integer -> Int# -> Integer
    shiftLInteger :: Integer -> Int# -> Integer
    shiftLInteger Integer
    n Int#
    i = Integer -> Word# -> Integer
    I.integerShiftL# Integer
    n (Int# -> Word#
    int2Word# Int#
    i)

    shiftRInteger :: Integer -> Int# -> Integer
    shiftRInteger :: Integer -> Int# -> Integer
    shiftRInteger Integer
    n Int#
    i = Integer -> Word# -> Integer
    I.integerShiftR# Integer
    n (Int# -> Word#
    int2Word# Int#
    i)

    testBitInteger :: Integer -> Int# -> Bool
    testBitInteger :: Integer -> Int# -> Bool
    testBitInteger Integer
    n Int#
    i = Int# -> Bool
    isTrue# (Integer -> Word# -> Int#
    I.integerTestBit# Integer
    n (Int# -> Word#
    int2Word# Int#
    i))

    hashInteger :: Integer -> Int#
    hashInteger :: Integer -> Int#
    hashInteger = Integer -> Int#
    I.integerToInt#

    bitInteger :: Int# -> Integer
    bitInteger :: Int# -> Integer
    bitInteger Int#
    i = Word# -> Integer
    I.integerBit# (Int# -> Word#
    int2Word# Int#
    i)

    popCountInteger :: Integer -> Int#
    popCountInteger :: Integer -> Int#
    popCountInteger = Integer -> Int#
    I.integerPopCount#