Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
1fc21753 by Sylvain Henry at 2026-05-29T13:18:14-04:00
ghc-bignum: copy backend interface haddocks to Native backend (#27305)
The haddock comments documenting the BigNat backend interface (function
contracts, expected MutableWordArray# sizes, return-value semantics, etc.)
were attached to the FFI backend module. Copy them to the Native backend
so they remain in tree once the FFI backend is removed.
Co-Authored-By: Claude Opus 4.7 (1M context)
- - - - -
717059df by Sylvain Henry at 2026-05-29T13:18:14-04:00
ghc-bignum: remove FFI backend (#27305)
The FFI backend of ghc-bignum (now part of ghc-internal) had no known
users and is easy to recreate by relinking ghc-internal with a custom
backend. Remove the backend module, the bignum-ffi cabal flag, and the
ffi option from Hadrian's --bignum selector. The backend interface
documentation now lives in the Native backend module.
Co-Authored-By: Claude Opus 4.7 (1M context)
- - - - -
4bb3b1d8 by Sylvain Henry at 2026-05-29T13:18:14-04:00
ghc-bignum: remove Check backend (#27305)
The Check backend of ghc-bignum (now part of ghc-internal) compared the
selected backend's output against the Native backend for validation.
It had no known users. Remove the backend module, the bignum-check
cabal flag, the bignumCheck Hadrian flavour field, and the check-
prefix in Hadrian's --bignum selector.
Co-Authored-By: Claude Opus 4.7 (1M context)
- - - - -
18 changed files:
- + changelog.d/remove-bignum-check-backend
- + changelog.d/remove-bignum-ffi-backend
- hadrian/README.md
- hadrian/doc/user-settings.md
- hadrian/src/CommandLine.hs
- hadrian/src/Flavour/Type.hs
- hadrian/src/Settings.hs
- hadrian/src/Settings/Builders/RunTest.hs
- hadrian/src/Settings/Default.hs
- hadrian/src/Settings/Packages.hs
- libraries/ghc-bignum/ghc-bignum.cabal
- libraries/ghc-internal/bignum-backend.rst
- libraries/ghc-internal/ghc-internal.cabal.in
- libraries/ghc-internal/src/GHC/Internal/Bignum/Backend.hs
- − libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Check.hs
- − libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/FFI.hs
- libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Native.hs
- − libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Selected.hs
Changes:
=====================================
changelog.d/remove-bignum-check-backend
=====================================
@@ -0,0 +1,11 @@
+section: packaging
+synopsis: Remove the Check backend of ghc-bignum
+issues: #27305
+mrs: !16106
+
+description: {
+ The Check backend of ghc-bignum (now part of ghc-internal), which compared
+ the results of the selected backend against the Native backend, has been
+ removed along with the ``bignum-check`` cabal flag and the ``check-``
+ prefix in Hadrian's ``--bignum`` option.
+}
=====================================
changelog.d/remove-bignum-ffi-backend
=====================================
@@ -0,0 +1,12 @@
+section: packaging
+synopsis: Remove the FFI backend of ghc-bignum
+issues: #27305
+mrs: !16106
+
+description: {
+ The FFI backend of ghc-bignum (now part of ghc-internal) has been removed.
+ It had no known users and was easy to recreate by relinking ghc-internal
+ with a custom backend implementation. As a result, the ``bignum-ffi``
+ cabal flag has been dropped, and selecting the ``ffi`` backend via
+ Hadrian's ``--bignum`` option is no longer supported.
+}
=====================================
hadrian/README.md
=====================================
@@ -101,7 +101,7 @@ Stage2 GHC.
* `--skip-depends`: skips rebuilding Haskell module dependency files.
-* `--bignum={native,gmp,check-gmp,ffi}`: **Deprecated.** Use the `+native_bignum` flavour
+* `--bignum={native,gmp}`: **Deprecated.** Use the `+native_bignum` flavour
transformer instead (e.g. `--flavour=default+native_bignum`). When building for the
JavaScript target, the native bignum backend is enabled automatically.
=====================================
hadrian/doc/user-settings.md
=====================================
@@ -24,10 +24,8 @@ data Flavour = Flavour {
extraArgs :: Args,
-- | Build these packages.
packages :: Stage -> Action [Package],
- -- | Bignum backend: 'native', 'gmp', 'ffi', etc.
+ -- | Bignum backend: 'native', 'gmp', etc.
bignumBackend :: String,
- -- | Check selected bignum backend against native backend
- bignumCheck :: Bool,
-- | Build the @text@ package with @simdutf@ support. Disabled by
-- default due to packaging difficulties described in #20724.
textWithSIMDUTF :: Bool,
=====================================
hadrian/src/CommandLine.hs
=====================================
@@ -1,7 +1,7 @@
module CommandLine (
optDescrs, cmdLineArgsMap, cmdFlavour, lookupFreeze1, lookupFreeze2, lookupSkipDepends,
lookupBignum,
- cmdBignum, cmdBignumCheck, cmdProgressInfo, cmdCompleteSetting,
+ cmdBignum, cmdProgressInfo, cmdCompleteSetting,
cmdDocsArgs, cmdUnitIdHash, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs,
cmdPrefix, cmdChangelogVersion, DocArgs(..), defaultDocArgs,
cmdKeepResponseFiles
@@ -32,7 +32,6 @@ data CommandLineArgs = CommandLineArgs
, skipDepends :: Bool
, unitIdHash :: Bool
, bignum :: Maybe String
- , bignumCheck :: Bool
, progressInfo :: ProgressInfo
, buildRoot :: BuildRoot
, testArgs :: TestArgs
@@ -54,7 +53,6 @@ defaultCommandLineArgs = CommandLineArgs
, skipDepends = False
, unitIdHash = False
, bignum = Nothing
- , bignumCheck = False
, progressInfo = Brief
, buildRoot = BuildRoot "_build"
, testArgs = defaultTestArgs
@@ -132,10 +130,7 @@ readFlavour ms = Right $ \flags -> flags { flavour = lower <$> ms }
readBignum :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs)
readBignum Nothing = Right id
-readBignum (Just ms) = Right $ \flags -> case break (== '-') (lower ms) of
- (backend,"") -> flags { bignum = Just backend }
- ("check",'-':backend) -> flags { bignum = Just backend, bignumCheck = True }
- _ -> flags { bignum = Just (lower ms) }
+readBignum (Just ms) = Right $ \flags -> flags { bignum = Just (lower ms) }
readBuildRoot :: FilePath -> Either String (CommandLineArgs -> CommandLineArgs)
readBuildRoot ms =
@@ -302,7 +297,7 @@ optDescrs =
, Option [] ["skip-depends"] (NoArg readSkipDepends)
"Skip rebuilding dependency information."
, Option [] ["bignum"] (OptArg readBignum "BACKEND")
- "Select bignum backend: native, gmp (default), check-gmp (gmp compared to native), ffi."
+ "Select bignum backend: native, gmp (default)."
, Option [] ["progress-info"] (ReqArg readProgressInfo "STYLE")
"Progress info style (None, Brief, Normal or Unicorn)."
, Option [] ["docs"] (ReqArg readDocsArg "TARGET")
@@ -429,9 +424,6 @@ cmdUnitIdHash = unitIdHash <$> cmdLineArgs
cmdBignum :: Action (Maybe String)
cmdBignum = bignum <$> cmdLineArgs
-cmdBignumCheck :: Action Bool
-cmdBignumCheck = bignumCheck <$> cmdLineArgs
-
cmdKeepResponseFiles :: Action Bool
cmdKeepResponseFiles = keepResponseFiles <$> cmdLineArgs
=====================================
hadrian/src/Flavour/Type.hs
=====================================
@@ -19,10 +19,8 @@ data Flavour = Flavour {
extraArgs :: Args,
-- | Build these packages.
packages :: Stage -> Action [Package],
- -- | Bignum backend: 'native', 'gmp', 'ffi', etc.
+ -- | Bignum backend: 'native', 'gmp', etc.
bignumBackend :: String,
- -- | Check selected bignum backend against native backend
- bignumCheck :: Bool,
-- | Build the @text@ package with @simdutf@ support. Disabled by
-- default due to packaging difficulties described in #20724.
textWithSIMDUTF :: Bool,
=====================================
hadrian/src/Settings.hs
=====================================
@@ -3,7 +3,7 @@
module Settings (
getExtraArgs, getArgs, getLibraryWays, getRtsWays, flavour, knownPackages,
findPackageByName, unsafeFindPackageByName, unsafeFindPackageByPath,
- isLibrary, stagePackages, getBignumBackend, getBignumCheck, completeSetting,
+ isLibrary, stagePackages, getBignumBackend, completeSetting,
queryBuildTarget, queryHostTarget, queryTargetTarget,
queryBuild, queryHost, queryTarget,
queryArch, queryOS, queryVendor
@@ -46,11 +46,6 @@ getRtsWays = expr flavour >>= rtsWays
getBignumBackend :: Expr String
getBignumBackend = bignumBackend <$> expr flavour
-getBignumCheck :: Expr Bool
-getBignumCheck = expr $ cmdBignum >>= \case
- Nothing -> bignumCheck <$> flavour
- Just _ -> cmdBignumCheck
-
stagePackages :: Stage -> Action [Package]
stagePackages stage = do
f <- flavour
=====================================
hadrian/src/Settings/Builders/RunTest.hs
=====================================
@@ -241,7 +241,6 @@ runTestBuilderArgs = builder Testsuite ? do
-- MP: TODO, these should be queried from the test compiler?
bignumBackend <- getBignumBackend
- bignumCheck <- getBignumCheck
keepFiles <- expr (testKeepFiles <$> userSetting defaultTestArgs)
@@ -307,7 +306,7 @@ runTestBuilderArgs = builder Testsuite ? do
, arg "-e", arg $ "ghc_compiler_always_flags=" ++ quote ghcFlags
, arg "-e", arg $ asBool "ghc_with_dynamic_rts=" (hasDynamicRts)
, arg "-e", arg $ asBool "config.ghc_with_threaded_rts=" (hasThreadedRts)
- , arg "-e", arg $ asBool "config.have_fast_bignum=" (bignumBackend /= "native" && not bignumCheck)
+ , arg "-e", arg $ asBool "config.have_fast_bignum=" (bignumBackend /= "native")
, arg "-e", arg $ asBool "config.target_has_smp=" targetWithSMP
, arg "-e", arg $ "config.ghc_dynamic=" ++ show hasDynamic
, arg "-e", arg $ "config.leading_underscore=" ++ show leadingUnderscore
=====================================
hadrian/src/Settings/Default.hs
=====================================
@@ -293,7 +293,6 @@ defaultFlavour = Flavour
, extraArgs = defaultExtraArgs
, packages = defaultPackages
, bignumBackend = defaultBignumBackend
- , bignumCheck = False
, textWithSIMDUTF = False
, libraryWays = defaultLibraryWays
, rtsWays = defaultRtsWays
=====================================
hadrian/src/Settings/Packages.hs
=====================================
@@ -240,15 +240,11 @@ ghcInternalArgs = package ghcInternal ? do
includesGmp <- getSetting GmpIncludeDir
backend <- getBignumBackend
- check <- getBignumCheck
mconcat
[ -- select bignum backend
builder (Cabal Flags) ? arg ("bignum-" <> backend)
- , -- check the selected backend against native backend
- builder (Cabal Flags) ? check `cabalFlag` "bignum-check"
-
-- backend specific
, case backend of
"gmp" -> mconcat
=====================================
libraries/ghc-bignum/ghc-bignum.cabal
=====================================
@@ -36,7 +36,7 @@ library
GHC.Internal.Bignum.Primitives as GHC.Num.Primitives
, GHC.Internal.Bignum.WordArray as GHC.Num.WordArray
, GHC.Internal.Bignum.Backend as GHC.Num.Backend
- , GHC.Internal.Bignum.Backend.Selected as GHC.Num.Backend.Selected
+ , GHC.Internal.Bignum.Backend as GHC.Num.Backend.Selected
, GHC.Internal.Bignum.Backend.Native as GHC.Num.Backend.Native
, GHC.Internal.Bignum.BigNat as GHC.Num.BigNat
, GHC.Internal.Bignum.Natural as GHC.Num.Natural
=====================================
libraries/ghc-internal/bignum-backend.rst
=====================================
@@ -33,20 +33,9 @@ supported:
integer-simple package. The major difference is that it uses a much more
efficient memory representation (integer-simple was based on Haskell lists)
and that it allows a lot more code sharing between the different backends than
- was previously possible between integer-gmp and integer-simple.
-
-* FFI: an implementation that relies on external FFI calls. This backend can be
- useful:
-
- * for alternative GHC backends that target non native platforms (JavaScript,
- JVM, etc.): the backend can dynamically match and rewrite the FFI calls in
- order to call the appropriate platform specific BigNum API.
-
- * to test new native backends: just tweak the ghc-bignum build to link with
- the native library providing the implementation of the FFI calls
-
- Note that the FFI backend module contains the description of the interface
- that needs to be implemented by every backend.
+ was previously possible between integer-gmp and integer-simple. The Native
+ backend module contains the description of the interface that needs to be
+ implemented by every backend.
This package has been designed to make the implementation of new backends
relatively easy. Previously you had to implement the whole Integer/Natural
=====================================
libraries/ghc-internal/ghc-internal.cabal.in
=====================================
@@ -56,21 +56,11 @@ Flag bignum-native
Manual: True
Default: False
-Flag bignum-ffi
- Description: Enable FFI bignum backend
- Manual: True
- Default: False
-
Flag bignum-gmp
Description: Enable GMP bignum backend
Manual: True
Default: False
-Flag bignum-check
- Description: Validate results of the enabled backend against native backend.
- Manual: True
- Default: False
-
Flag need-atomic
Description: Enable linking with "atomic" library (for 64-bit atomic ops on armel, #20549)
Manual: True
@@ -382,13 +372,11 @@ Library
-- Bignum configuration
----------------------------------------
-- check that at least one backend is enabled
- if !flag(bignum-native) && !flag(bignum-gmp) && !flag(bignum-ffi)
+ if !flag(bignum-native) && !flag(bignum-gmp)
buildable: False
-- check that at most one flag is set
- if flag(bignum-native) && (flag(bignum-gmp) || flag(bignum-ffi))
- buildable: False
- if flag(bignum-gmp) && flag(bignum-ffi)
+ if flag(bignum-native) && flag(bignum-gmp)
buildable: False
if flag(bignum-gmp)
@@ -398,25 +386,14 @@ Library
c-sources:
cbits/gmp_wrappers.c
- if flag(bignum-ffi)
- cpp-options: -DBIGNUM_FFI
- other-modules:
- GHC.Internal.Bignum.Backend.FFI
-
if flag(bignum-native)
cpp-options: -DBIGNUM_NATIVE
- if flag(bignum-check)
- cpp-options: -DBIGNUM_CHECK
- other-modules:
- GHC.Internal.Bignum.Backend.Check
-
exposed-modules:
GHC.Internal.Bignum.Primitives
GHC.Internal.Bignum.WordArray
GHC.Internal.Bignum.BigNat
GHC.Internal.Bignum.Backend
- GHC.Internal.Bignum.Backend.Selected
GHC.Internal.Bignum.Backend.Native
GHC.Internal.Bignum.Natural
GHC.Internal.Bignum.Integer
=====================================
libraries/ghc-internal/src/GHC/Internal/Bignum/Backend.hs
=====================================
@@ -7,9 +7,12 @@ module GHC.Internal.Bignum.Backend
)
where
-#if defined(BIGNUM_CHECK)
-import GHC.Internal.Bignum.Backend.Check as Backend
+#if defined(BIGNUM_NATIVE)
+import GHC.Internal.Bignum.Backend.Native as Backend
+
+#elif defined(BIGNUM_GMP)
+import GHC.Internal.Bignum.Backend.GMP as Backend
+
#else
-import GHC.Internal.Bignum.Backend.Selected as Backend
+#error Undefined BigNum backend. Use a flag to select it (e.g. gmp, native)`
#endif
-
=====================================
libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Check.hs deleted
=====================================
@@ -1,508 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE NoImplicitPrelude #-}
-{-# LANGUAGE BangPatterns #-}
-{-# LANGUAGE GHCForeignImportPrim #-}
-{-# LANGUAGE MagicHash #-}
-{-# LANGUAGE UnboxedTuples #-}
-{-# LANGUAGE UnliftedFFITypes #-}
-{-# LANGUAGE NegativeLiterals #-}
-{-# LANGUAGE ForeignFunctionInterface #-}
-{-# OPTIONS_GHC -Wno-name-shadowing #-}
-
--- | Check Native implementation against another backend
-module GHC.Internal.Bignum.Backend.Check where
-
-import GHC.Internal.CString
-import GHC.Internal.Prim
-import GHC.Internal.Types
-import GHC.Internal.Bignum.WordArray
-import GHC.Internal.Bignum.Primitives
-import {-# SOURCE #-} GHC.Internal.Bignum.Integer
-import {-# SOURCE #-} GHC.Internal.Bignum.Natural
-import qualified GHC.Internal.Bignum.Backend.Native as Native
-import qualified GHC.Internal.Bignum.Backend.Selected as Other
-
-#if defined(BIGNUM_NATIVE)
-#error You can't validate Native backend against itself. Choose another backend (e.g. gmp, ffi)
-#endif
-
-default ()
-
--- | ghc-bignum backend name
-backendName :: [Char]
-backendName = unpackAppendCString# "check-"# Other.backendName
- -- we don't have (++) at our disposal, so we directly use
- -- `unpackAppendCString#`
-
-bignat_compare
- :: WordArray#
- -> WordArray#
- -> Int#
-bignat_compare a b =
- let
- gr = Other.bignat_compare a b
- nr = Native.bignat_compare a b
- in case gr ==# nr of
- 0# -> unexpectedValue_Int# (# #)
- _ -> gr
-
-mwaCompare
- :: MutableWordArray# s
- -> MutableWordArray# s
- -> State# s
- -> (# State# s, Bool# #)
-mwaCompare mwa mwb s =
- case mwaSize# mwa s of
- (# s, szA #) -> case mwaSize# mwb s of
- (# s, szB #) -> case szA ==# szB of
- 0# -> (# s, 0# #)
- _ -> let
- go i s
- | isTrue# (i <# 0#) = (# s, 1# #)
- | True =
- case readWordArray# mwa i s of
- (# s, a #) -> case readWordArray# mwb i s of
- (# s, b #) -> case a `eqWord#` b of
- 0# -> (# s, 0# #)
- _ -> go (i -# 1#) s
- in go (szA -# 1#) s
-
-mwaCompareOp
- :: MutableWordArray# s
- -> (MutableWordArray# s -> State# s -> State# s)
- -> (MutableWordArray# s -> State# s -> State# s)
- -> State# s
- -> State# s
-mwaCompareOp mwa f g s =
- case mwaSize# mwa s of { (# s, sz #) ->
- case newWordArray# sz s of { (# s, mwb #) ->
- case f mwa s of { s ->
- case g mwb s of { s ->
- case mwaTrimZeroes# mwa s of { s ->
- case mwaTrimZeroes# mwb s of { s ->
- case mwaCompare mwa mwb s of
- (# s, 0# #) -> case unexpectedValue of
- !_ -> s
- -- see Note [ghc-bignum exceptions] in
- -- GHC.Num.Primitives
- (# s, _ #) -> s
- }}}}}}
-
-mwaCompareOp2
- :: MutableWordArray# s
- -> MutableWordArray# s
- -> (MutableWordArray# s -> MutableWordArray# s -> State# s -> State# s)
- -> (MutableWordArray# s -> MutableWordArray# s -> State# s -> State# s)
- -> State# s
- -> State# s
-mwaCompareOp2 mwa mwb f g s =
- case mwaSize# mwa s of { (# s, szA #) ->
- case mwaSize# mwb s of { (# s, szB #) ->
- case newWordArray# szA s of { (# s, mwa' #) ->
- case newWordArray# szB s of { (# s, mwb' #) ->
- case f mwa mwb s of { s ->
- case g mwa' mwb' s of { s ->
- case mwaTrimZeroes# mwa s of { s ->
- case mwaTrimZeroes# mwb s of { s ->
- case mwaTrimZeroes# mwa' s of { s ->
- case mwaTrimZeroes# mwb' s of { s ->
- case mwaCompare mwa mwa' s of { (# s, ba #) ->
- case mwaCompare mwb mwb' s of { (# s, bb #) ->
- case ba & bb of
- 0# -> case unexpectedValue of
- !_ -> s
- -- see Note [ghc-bignum exceptions] in GHC.Num.Primitives
- _ -> s
- }}}}}}}}}}}}
-
-mwaCompareOpBool
- :: MutableWordArray# s
- -> (MutableWordArray# s -> State# s -> (#State# s, Bool# #))
- -> (MutableWordArray# s -> State# s -> (#State# s, Bool# #))
- -> State# s
- -> (# State# s, Bool# #)
-mwaCompareOpBool mwa f g s =
- case mwaSize# mwa s of { (# s, sz #) ->
- case newWordArray# sz s of { (# s, mwb #) ->
- case f mwa s of { (# s, ra #) ->
- case g mwb s of { (# s, rb #) ->
- case ra ==# rb of
- 0# -> case unexpectedValue of
- !_ -> (# s, ra #)
- -- see Note [ghc-bignum exceptions] in GHC.Num.Primitives
- _ -> case ra of -- don't compare MWAs if underflow signaled!
- 0# -> (# s, ra #) -- underflow
- _ -> case mwaTrimZeroes# mwa s of { s ->
- case mwaTrimZeroes# mwb s of { s ->
- case mwaCompare mwa mwb s of
- (# s, 0# #) -> case unexpectedValue of
- !_ -> (# s, ra #)
- -- see Note [ghc-bignum exceptions] in
- -- GHC.Num.Primitives
- _ -> (# s, ra #)
- }}}}}}
-
-mwaCompareOpWord
- :: MutableWordArray# s
- -> (MutableWordArray# s -> State# s -> (#State# s, Word# #))
- -> (MutableWordArray# s -> State# s -> (#State# s, Word# #))
- -> State# s
- -> (# State# s, Word# #)
-mwaCompareOpWord mwa f g s =
- case mwaSize# mwa s of { (# s, sz #) ->
- case newWordArray# sz s of { (# s, mwb #) ->
- case f mwa s of { (# s, ra #) ->
- case g mwb s of { (# s, rb #) ->
- case mwaTrimZeroes# mwa s of { s ->
- case mwaTrimZeroes# mwb s of { s ->
- case mwaCompare mwa mwb s of
- (# s, b #) -> case b & (ra `eqWord#` rb) of
- 0# -> case unexpectedValue of
- !_ -> (# s, ra #)
- -- see Note [ghc-bignum exceptions] in GHC.Num.Primitives
- _ -> (# s, ra #)
- }}}}}}
-
-bignat_add
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_add mwa wa wb
- = mwaCompareOp mwa
- (\m -> Other.bignat_add m wa wb)
- (\m -> Native.bignat_add m wa wb)
-
-bignat_add_word
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> State# RealWorld
-bignat_add_word mwa wa b
- = mwaCompareOp mwa
- (\m -> Other.bignat_add_word m wa b)
- (\m -> Native.bignat_add_word m wa b)
-
-bignat_mul_word
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> State# RealWorld
-bignat_mul_word mwa wa b
- = mwaCompareOp mwa
- (\m -> Other.bignat_mul_word m wa b)
- (\m -> Native.bignat_mul_word m wa b)
-
-bignat_sub
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> (# State# RealWorld, Bool# #)
-bignat_sub mwa wa wb
- = mwaCompareOpBool mwa
- (\m -> Other.bignat_sub m wa wb)
- (\m -> Native.bignat_sub m wa wb)
-
-bignat_sub_word
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> (# State# RealWorld, Bool# #)
-bignat_sub_word mwa wa b
- = mwaCompareOpBool mwa
- (\m -> Other.bignat_sub_word m wa b)
- (\m -> Native.bignat_sub_word m wa b)
-
-bignat_mul
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_mul mwa wa wb
- = mwaCompareOp mwa
- (\m -> Other.bignat_mul m wa wb)
- (\m -> Native.bignat_mul m wa wb)
-
-bignat_popcount :: WordArray# -> Word#
-bignat_popcount wa =
- let
- gr = Other.bignat_popcount wa
- nr = Native.bignat_popcount wa
- in case gr `eqWord#` nr of
- 0# -> 1## `quotWord#` 0##
- _ -> gr
-
-bignat_shiftl
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> State# RealWorld
-bignat_shiftl mwa wa n
- = mwaCompareOp mwa
- (\m -> Other.bignat_shiftl m wa n)
- (\m -> Native.bignat_shiftl m wa n)
-
-bignat_shiftr
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> State# RealWorld
-bignat_shiftr mwa wa n
- = mwaCompareOp mwa
- (\m -> Other.bignat_shiftr m wa n)
- (\m -> Native.bignat_shiftr m wa n)
-
-bignat_shiftr_neg
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> State# RealWorld
-bignat_shiftr_neg mwa wa n
- = mwaCompareOp mwa
- (\m -> Other.bignat_shiftr_neg m wa n)
- (\m -> Native.bignat_shiftr_neg m wa n)
-
-bignat_or
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_or mwa wa wb
- = mwaCompareOp mwa
- (\m -> Other.bignat_or m wa wb)
- (\m -> Native.bignat_or m wa wb)
-
-bignat_xor
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_xor mwa wa wb
- = mwaCompareOp mwa
- (\m -> Other.bignat_xor m wa wb)
- (\m -> Native.bignat_xor m wa wb)
-
-bignat_and
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_and mwa wa wb
- = mwaCompareOp mwa
- (\m -> Other.bignat_and m wa wb)
- (\m -> Native.bignat_and m wa wb)
-
-bignat_and_not
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_and_not mwa wa wb
- = mwaCompareOp mwa
- (\m -> Other.bignat_and_not m wa wb)
- (\m -> Native.bignat_and_not m wa wb)
-
-bignat_quotrem
- :: MutableWordArray# RealWorld
- -> MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_quotrem mwq mwr wa wb
- = mwaCompareOp2 mwq mwr
- (\m1 m2 -> Other.bignat_quotrem m1 m2 wa wb)
- (\m1 m2 -> Native.bignat_quotrem m1 m2 wa wb)
-
-bignat_quot
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_quot mwq wa wb
- = mwaCompareOp mwq
- (\m -> Other.bignat_quot m wa wb)
- (\m -> Native.bignat_quot m wa wb)
-
-bignat_rem
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_rem mwr wa wb
- = mwaCompareOp mwr
- (\m -> Other.bignat_rem m wa wb)
- (\m -> Native.bignat_rem m wa wb)
-
-bignat_quotrem_word
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> (# State# RealWorld, Word# #)
-bignat_quotrem_word mwq wa b
- = mwaCompareOpWord mwq
- (\m -> Other.bignat_quotrem_word m wa b)
- (\m -> Native.bignat_quotrem_word m wa b)
-
-bignat_quot_word
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> State# RealWorld
-bignat_quot_word mwq wa b
- = mwaCompareOp mwq
- (\m -> Other.bignat_quot_word m wa b)
- (\m -> Native.bignat_quot_word m wa b)
-
-bignat_rem_word
- :: WordArray#
- -> Word#
- -> Word#
-bignat_rem_word wa b =
- let
- gr = Other.bignat_rem_word wa b
- nr = Native.bignat_rem_word wa b
- in case gr `eqWord#` nr of
- 1# -> gr
- _ -> unexpectedValue_Word# (# #)
-
-bignat_gcd
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_gcd mwr wa wb
- = mwaCompareOp mwr
- (\m -> Other.bignat_gcd m wa wb)
- (\m -> Native.bignat_gcd m wa wb)
-
-bignat_gcd_word
- :: WordArray#
- -> Word#
- -> Word#
-bignat_gcd_word wa b =
- let
- gr = Other.bignat_gcd_word wa b
- nr = Native.bignat_gcd_word wa b
- in case gr `eqWord#` nr of
- 1# -> gr
- _ -> unexpectedValue_Word# (# #)
-
-bignat_gcd_word_word
- :: Word#
- -> Word#
- -> Word#
-bignat_gcd_word_word a b =
- let
- gr = Other.bignat_gcd_word_word a b
- nr = Native.bignat_gcd_word_word a b
- in case gr `eqWord#` nr of
- 1# -> gr
- _ -> unexpectedValue_Word# (# #)
-
-bignat_encode_double :: WordArray# -> Int# -> Double#
-bignat_encode_double a e =
- let
- gr = Other.bignat_encode_double a e
- nr = Native.bignat_encode_double a e
- in case gr ==## nr of
- 1# -> gr
- _ -> case unexpectedValue of
- !_ -> 0.0##
- -- see Note [ghc-bignum exceptions] in GHC.Num.Primitives
-
-bignat_powmod_word :: WordArray# -> WordArray# -> Word# -> Word#
-bignat_powmod_word b e m =
- let
- gr = Other.bignat_powmod_word b e m
- nr = Native.bignat_powmod_word b e m
- in case gr `eqWord#` nr of
- 1# -> gr
- _ -> unexpectedValue_Word# (# #)
-
-bignat_powmod
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_powmod r b e m
- = mwaCompareOp r
- (\r' -> Other.bignat_powmod r' b e m)
- (\r' -> Native.bignat_powmod r' b e m)
-
-bignat_powmod_words
- :: Word#
- -> Word#
- -> Word#
- -> Word#
-bignat_powmod_words b e m =
- let
- gr = Other.bignat_powmod_words b e m
- nr = Native.bignat_powmod_words b e m
- in case gr `eqWord#` nr of
- 1# -> gr
- _ -> unexpectedValue_Word# (# #)
-
-integer_gcde
- :: Integer
- -> Integer
- -> (# Integer, Integer, Integer #)
-integer_gcde a b =
- let
- !(# g0,x0,y0 #) = Other.integer_gcde a b
- !(# g1,x1,y1 #) = Native.integer_gcde a b
- in if isTrue# (integerEq# x0 x1
- & integerEq# y0 y1
- & integerEq# g0 g1)
- then (# g0, x0, y0 #)
- else case unexpectedValue of
- !_ -> (# integerZero, integerZero, integerZero #)
-
-integer_recip_mod
- :: Integer
- -> Natural
- -> (# Natural | () #)
-integer_recip_mod x m =
- let
- !r0 = Other.integer_recip_mod x m
- !r1 = Native.integer_recip_mod x m
- in case (# r0, r1 #) of
- (# (# | () #), (# | () #) #) -> r0
- (# (# y0 | #), (# y1 | #) #)
- | isTrue# (naturalEq# y0 y1) -> r0
- _ -> case unexpectedValue of
- !_ -> (# | () #)
-
-integer_powmod
- :: Integer
- -> Natural
- -> Natural
- -> Natural
-integer_powmod b e m =
- let
- !r0 = Other.integer_powmod b e m
- !r1 = Native.integer_powmod b e m
- in if isTrue# (naturalEq# r0 r1)
- then r0
- else case unexpectedValue of
- !_ -> naturalZero
=====================================
libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/FFI.hs deleted
=====================================
@@ -1,641 +0,0 @@
-{-# LANGUAGE NoImplicitPrelude #-}
-{-# LANGUAGE BangPatterns #-}
-{-# LANGUAGE GHCForeignImportPrim #-}
-{-# LANGUAGE MagicHash #-}
-{-# LANGUAGE UnboxedTuples #-}
-{-# LANGUAGE UnliftedFFITypes #-}
-{-# LANGUAGE NegativeLiterals #-}
-{-# LANGUAGE ForeignFunctionInterface #-}
-
--- | External BigNat backend that directly call FFI operations.
---
--- This backend can be useful for specific compilers such as GHCJS or Asterius
--- that replace bignat foreign calls with calls to the native platform bignat
--- library (e.g. JavaScript's BigInt). You can also link an extra object
--- providing the implementation.
-module GHC.Internal.Bignum.Backend.FFI where
-
-import GHC.Internal.Prim
-import GHC.Internal.Types
-import GHC.Internal.Bignum.WordArray
-import GHC.Internal.Bignum.Primitives
-import qualified GHC.Internal.Bignum.Backend.Native as Native
-import {-# SOURCE #-} GHC.Internal.Bignum.Natural
-import {-# SOURCE #-} GHC.Internal.Bignum.Integer
-
--- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
--- (This module uses the empty tuple () and string literals.)
-import GHC.Internal.Tuple ()
-import GHC.Internal.CString ()
-
-default ()
-
--- | ghc-bignum backend name
-backendName :: [Char]
-backendName = "ffi"
-
--- | Compare two non-zero BigNat of the same length
---
--- Return:
--- < 0 ==> LT
--- == 0 ==> EQ
--- > 0 ==> GT
-bignat_compare
- :: WordArray#
- -> WordArray#
- -> Int#
-bignat_compare = ghc_bignat_compare
-
-foreign import ccall unsafe ghc_bignat_compare
- :: WordArray#
- -> WordArray#
- -> Int#
-
--- | Add two non-zero BigNat
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: max (size a, size b) + 1
---
--- The potential 0 most-significant Word (i.e. the potential carry) will be
--- removed by the caller if it is not already done by the backend.
-bignat_add
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_add mwa wa wb s
- = ioVoid (ghc_bignat_add mwa wa wb) s
-
-foreign import ccall unsafe ghc_bignat_add
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> WordArray#
- -> IO ()
-
--- | Add a non-zero BigNat and a non-zero Word#
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: size a + 1
---
--- The potential 0 most-significant Word (i.e. the potential carry) will be
--- removed by the caller if it is not already done by the backend.
-bignat_add_word
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> State# RealWorld
-bignat_add_word mwa wa b s =
- ioVoid (ghc_bignat_add_word mwa wa b) s
-
-foreign import ccall unsafe ghc_bignat_add_word
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> Word#
- -> IO ()
-
--- | Multiply a non-zero BigNat and a non-zero Word#
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: size a + 1
---
--- The potential 0 most-significant Word (i.e. the potential carry) will be
--- removed by the caller if it is not already done by the backend.
-bignat_mul_word
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> State# RealWorld
-bignat_mul_word mwa wa b s =
- ioVoid (ghc_bignat_mul_word mwa wa b) s
-
-foreign import ccall unsafe ghc_bignat_mul_word
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> Word#
- -> IO ()
-
--- | Sub two non-zero BigNat
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: size a
---
--- The potential 0 most-significant Words will be removed by the caller if it is
--- not already done by the backend.
---
--- Return False# to indicate underflow.
-bignat_sub
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> (# State# RealWorld, Bool# #)
-bignat_sub mwa wa wb s = ioBool (ghc_bignat_sub mwa wa wb) s
-
-foreign import ccall unsafe ghc_bignat_sub
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> WordArray#
- -> IO Bool
-
--- | Sub a non-zero word from a non-zero BigNat
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: size a
---
--- The potential 0 most-significant Words will be removed by the caller if it is
--- not already done by the backend.
---
--- Return False# to indicate underflow.
-bignat_sub_word
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> (# State# RealWorld, Bool# #)
-bignat_sub_word mwa wa b s = ioBool (ghc_bignat_sub_word mwa wa b) s
-
-foreign import ccall unsafe ghc_bignat_sub_word
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> Word#
- -> IO Bool
-
--- | Multiply two non-zero BigNat
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: size a+size b
---
--- The potential 0 most-significant Word (i.e. the potential carry) will be
--- removed by the caller if it is not already done by the backend.
-bignat_mul
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_mul mwa wa wb s = ioVoid (ghc_bignat_mul mwa wa wb) s
-
-foreign import ccall unsafe ghc_bignat_mul
- :: MutableWordArray# RealWorld -- ^ Result
- -> WordArray#
- -> WordArray#
- -> IO ()
-
--- | PopCount of a non-zero BigNat
-bignat_popcount :: WordArray# -> Word#
-bignat_popcount = ghc_bignat_popcount
-
-foreign import ccall unsafe ghc_bignat_popcount
- :: WordArray#
- -> Word#
-
--- | Left-shift a non-zero BigNat by a non-zero amount of bits
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: size a + required new limbs
---
--- The potential 0 most-significant Word (i.e. the potential carry) will be
--- removed by the caller if it is not already done by the backend.
-bignat_shiftl
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> State# RealWorld
-bignat_shiftl mwa wa n s = ioVoid (ghc_bignat_shiftl mwa wa n) s
-
-foreign import ccall unsafe ghc_bignat_shiftl
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> IO ()
-
--- | Right-shift a non-zero BigNat by a non-zero amount of bits
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: required limbs
---
--- The potential 0 most-significant Word (i.e. the potential carry) will be
--- removed by the caller if it is not already done by the backend.
-bignat_shiftr
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> State# RealWorld
-bignat_shiftr mwa wa n s = ioVoid (ghc_bignat_shiftr mwa wa n) s
-
-foreign import ccall unsafe ghc_bignat_shiftr
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> IO ()
-
--- | Right-shift a non-zero BigNat by a non-zero amount of bits by first
--- converting it into its two's complement representation and then again after
--- the arithmetic shift.
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: required limbs
---
--- The potential 0 most-significant Words (i.e. the potential carry) will be
--- removed by the caller if it is not already done by the backend.
-bignat_shiftr_neg
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> State# RealWorld
-bignat_shiftr_neg mwa wa n s = ioVoid (ghc_bignat_shiftr_neg mwa wa n) s
-
-foreign import ccall unsafe ghc_bignat_shiftr_neg
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> IO ()
-
-
--- | OR two non-zero BigNat
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: max (size a, size b)
-bignat_or
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-{-# INLINE bignat_or #-}
-bignat_or mwa wa wb s = ioVoid (ghc_bignat_or mwa wa wb) s
-
-foreign import ccall unsafe ghc_bignat_or
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> IO ()
-
--- | XOR two non-zero BigNat
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: max (size a, size b)
---
--- The potential 0 most-significant Words will be removed by the caller if it is
--- not already done by the backend.
-bignat_xor
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-{-# INLINE bignat_xor #-}
-bignat_xor mwa wa wb s = ioVoid (ghc_bignat_xor mwa wa wb) s
-
-foreign import ccall unsafe ghc_bignat_xor
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> IO ()
-
--- | AND two non-zero BigNat
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: min (size a, size b)
---
--- The potential 0 most-significant Words will be removed by the caller if it is
--- not already done by the backend.
-bignat_and
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-{-# INLINE bignat_and #-}
-bignat_and mwa wa wb s = ioVoid (ghc_bignat_and mwa wa wb) s
-
-foreign import ccall unsafe ghc_bignat_and
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> IO ()
-
--- | ANDNOT two non-zero BigNat
---
--- Result is to be stored in the MutableWordArray#.
--- The latter has size: size a
---
--- The potential 0 most-significant Words will be removed by the caller if it is
--- not already done by the backend.
-bignat_and_not
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-{-# INLINE bignat_and_not #-}
-bignat_and_not mwa wa wb s = ioVoid (ghc_bignat_and_not mwa wa wb) s
-
-foreign import ccall unsafe ghc_bignat_and_not
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> IO ()
-
--- | QuotRem of two non-zero BigNat
---
--- Result quotient and remainder are to be stored in the MutableWordArray#.
--- The first one (quotient) has size: size(A)-size(B)+1
--- The second one (remainder) has size: size(b)
---
--- The potential 0 most-significant Words will be removed by the caller if it is
--- not already done by the backend.
-bignat_quotrem
- :: MutableWordArray# RealWorld -- ^ Quotient
- -> MutableWordArray# RealWorld -- ^ Remainder
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_quotrem mwq mwr wa wb s =
- ioVoid (ghc_bignat_quotrem mwq mwr wa wb) s
-
-foreign import ccall unsafe ghc_bignat_quotrem
- :: MutableWordArray# RealWorld
- -> MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> IO ()
-
--- | Quotient of two non-zero BigNat
---
--- Result quotient is to be stored in the MutableWordArray#.
--- The latter has size: size(A)-size(B)+1
---
--- The potential 0 most-significant Words will be removed by the caller if it is
--- not already done by the backend.
-bignat_quot
- :: MutableWordArray# RealWorld -- ^ Quotient
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_quot mwq wa wb s =
- ioVoid (ghc_bignat_quot mwq wa wb) s
-
-foreign import ccall unsafe ghc_bignat_quot
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> IO ()
-
--- | Remainder of two non-zero BigNat
---
--- Result remainder is to be stored in the MutableWordArray#.
--- The latter has size: size(B)
---
--- The potential 0 most-significant Words will be removed by the caller if it is
--- not already done by the backend.
-bignat_rem
- :: MutableWordArray# RealWorld -- ^ Quotient
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_rem mwr wa wb s =
- ioVoid (ghc_bignat_rem mwr wa wb) s
-
-foreign import ccall unsafe ghc_bignat_rem
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> IO ()
-
--- | QuotRem of a non-zero BigNat and a non-zero Word
---
--- Result quotient is to be stored in the MutableWordArray#.
--- The latter has size: size(A)
---
--- The remainder is returned.
---
--- The potential 0 most-significant Words will be removed by the caller if it is
--- not already done by the backend.
-bignat_quotrem_word
- :: MutableWordArray# RealWorld -- ^ Quotient
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> (# State# RealWorld, Word# #)
-bignat_quotrem_word mwq wa b s =
- ioWord# (ghc_bignat_quotrem_word mwq wa b) s
-
-foreign import ccall unsafe ghc_bignat_quotrem_word
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> IO Word
-
--- | Quot of a non-zero BigNat and a non-zero Word
---
--- Result quotient is to be stored in the MutableWordArray#.
--- The latter has size: size(A)
---
--- The potential 0 most-significant Words will be removed by the caller if it is
--- not already done by the backend.
-bignat_quot_word
- :: MutableWordArray# RealWorld -- ^ Quotient
- -> WordArray#
- -> Word#
- -> State# RealWorld
- -> State# RealWorld
-bignat_quot_word mwq wa b s =
- ioVoid (ghc_bignat_quot_word mwq wa b) s
-
-foreign import ccall unsafe ghc_bignat_quot_word
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> Word#
- -> IO ()
-
--- | Remainder of a non-zero BigNat and a non-zero Word
---
--- The remainder is returned.
-bignat_rem_word
- :: WordArray#
- -> Word#
- -> Word#
-bignat_rem_word = ghc_bignat_rem_word
-
-foreign import ccall unsafe ghc_bignat_rem_word
- :: WordArray#
- -> Word#
- -> Word#
-
-
--- | Greatest common divisor (GCD) of two non-zero and non-one BigNat
---
--- Result GCD is to be stored in the MutableWordArray#.
--- The latter has size: size(B)
--- The first WordArray# is greater than the second WordArray#.
---
--- The potential 0 most-significant Words will be removed by the caller if it is
--- not already done by the backend.
-bignat_gcd
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_gcd mwr wa wb s =
- ioVoid (ghc_bignat_gcd mwr wa wb) s
-
-foreign import ccall unsafe ghc_bignat_gcd
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> IO ()
-
--- | Greatest common divisor (GCD) of a non-zero/non-one BigNat and a
--- non-zero/non-one Word#
---
--- Result GCD is returned
-bignat_gcd_word
- :: WordArray#
- -> Word#
- -> Word#
-bignat_gcd_word = ghc_bignat_gcd_word
-
-foreign import ccall unsafe ghc_bignat_gcd_word
- :: WordArray#
- -> Word#
- -> Word#
-
--- | Greatest common divisor (GCD) of two Word#
---
--- Result GCD is returned
-bignat_gcd_word_word
- :: Word#
- -> Word#
- -> Word#
-bignat_gcd_word_word = ghc_bignat_gcd_word_word
-
-foreign import ccall unsafe ghc_bignat_gcd_word_word
- :: Word#
- -> Word#
- -> Word#
-
--- | Encode (# BigNat mantissa, Int# exponent #) into a Double#
-bignat_encode_double :: WordArray# -> Int# -> Double#
-bignat_encode_double = ghc_bignat_encode_double
-
-foreign import ccall unsafe ghc_bignat_encode_double
- :: WordArray#
- -> Int#
- -> Double#
-
--- | \"@'bignat_powmod_word' /b/ /e/ /m/@\" computes base @/b/@ raised to
--- exponent @/e/@ modulo @/m/@.
---
--- b > 1
--- e > 0
--- m > 1
-bignat_powmod_word :: WordArray# -> WordArray# -> Word# -> Word#
-bignat_powmod_word = ghc_bignat_powmod_word
-
-foreign import ccall unsafe ghc_bignat_powmod_word
- :: WordArray# -> WordArray# -> Word# -> Word#
-
--- | \"@'bignat_powmod' r /b/ /e/ /m/@\" computes base @/b/@ raised to
--- exponent @/e/@ modulo @/m/@.
---
--- b > 1
--- e > 0
--- m > 1
---
--- Result is to be stored in the MutableWordArray# (which size is equal to the
--- one of m).
---
--- The potential 0 most-significant Words will be removed by the caller if it is
--- not already done by the backend.
-bignat_powmod
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> WordArray#
- -> State# RealWorld
- -> State# RealWorld
-bignat_powmod r b e m s =
- ioVoid (ghc_bignat_powmod r b e m) s
-
-foreign import ccall unsafe ghc_bignat_powmod
- :: MutableWordArray# RealWorld
- -> WordArray#
- -> WordArray#
- -> WordArray#
- -> IO ()
-
--- | \"@'bignat_powmod' /b/ /e/ /m/@\" computes base @/b/@ raised to
--- exponent @/e/@ modulo @/m/@.
---
--- b > 1
--- e > 0
--- m > 1
-bignat_powmod_words
- :: Word#
- -> Word#
- -> Word#
- -> Word#
-bignat_powmod_words = ghc_bignat_powmod_words
-
-foreign import ccall unsafe ghc_bignat_powmod_words
- :: Word# -> Word# -> Word# -> Word#
-
-
--- | Return extended GCD of two non-zero integers.
---
--- I.e. integer_gcde a b returns (g,x,y) so that ax + by = g
---
--- Input: a and b are non zero.
--- Output: g must be > 0
---
-integer_gcde
- :: Integer
- -> Integer
- -> (# Integer, Integer, Integer #)
-integer_gcde = Native.integer_gcde
- -- for now we use Native's implementation. If some FFI backend user needs a
- -- specific implementation, we'll need to determine a prototype to pass and
- -- return BigNat signs and sizes via FFI.
-
-
--- | Computes the modular inverse of two non-zero integers.
---
--- I.e. y = integer_recip_mod x m
--- = x^(-1) `mod` m
---
--- with 0 < y < abs m
-integer_recip_mod
- :: Integer
- -> Natural
- -> (# Natural | () #)
-integer_recip_mod = Native.integer_recip_mod
- -- for now we use Native's implementation. If some FFI backend user needs a
- -- specific implementation, we'll need to determine a prototype to pass and
- -- return BigNat signs and sizes via FFI.
-
--- | Computes the modular exponentiation.
---
--- I.e. y = integer_powmod b e m
--- = b^e `mod` m
---
--- with 0 <= y < abs m
-integer_powmod
- :: Integer
- -> Natural
- -> Natural
- -> Natural
-integer_powmod = Native.integer_powmod
- -- for now we use Native's implementation. If some FFI backend user needs a
- -- specific implementation, we'll need to determine a prototype to pass and
- -- return BigNat signs and sizes via FFI.
=====================================
libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Native.hs
=====================================
@@ -14,7 +14,7 @@ module GHC.Internal.Bignum.Backend.Native where
#include "MachDeps.h"
#include "WordSize.h"
-#if defined(BIGNUM_NATIVE) || defined(BIGNUM_CHECK) || defined(BIGNUM_FFI)
+#if defined(BIGNUM_NATIVE)
import {-# SOURCE #-} GHC.Internal.Bignum.BigNat
import {-# SOURCE #-} GHC.Internal.Bignum.Natural
import {-# SOURCE #-} GHC.Internal.Bignum.Integer
@@ -50,6 +50,12 @@ count_words_bits_int :: Word# -> (# Int#, Int# #)
count_words_bits_int n = case count_words_bits n of
(# nw, nb #) -> (# word2Int# nw, word2Int# nb #)
+-- | Compare two non-zero BigNat of the same length
+--
+-- Return:
+-- < 0 ==> LT
+-- == 0 ==> EQ
+-- > 0 ==> GT
bignat_compare :: WordArray# -> WordArray# -> Int#
bignat_compare wa wb = go (sz -# 1#)
where
@@ -62,6 +68,13 @@ bignat_compare wa wb = go (sz -# 1#)
| isTrue# (a `gtWord#` b) -> 1#
| True -> -1#
+-- | Add two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: max (size a, size b) + 1
+--
+-- The potential 0 most-significant Word (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
bignat_add
:: MutableWordArray# s -- ^ Result
-> WordArray#
@@ -120,6 +133,13 @@ bignat_add mwa wa wb = addABc 0# 0##
in case mwaWrite# mwa i r s of
s' -> addAoBc wab (i +# 1#) carry' s'
+-- | Add a non-zero BigNat and a non-zero Word#
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a + 1
+--
+-- The potential 0 most-significant Word (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
bignat_add_word
:: MutableWordArray# RealWorld -- ^ Result
-> WordArray#
@@ -128,6 +148,15 @@ bignat_add_word
-> State# RealWorld
bignat_add_word mwa wa b s = mwaInitArrayPlusWord mwa wa b s
+-- | Sub a non-zero word from a non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+--
+-- Return False# to indicate underflow.
bignat_sub_word
:: MutableWordArray# RealWorld
-> WordArray#
@@ -154,6 +183,13 @@ bignat_sub_word mwa wa b = go b 0#
(# l , c #) -> case mwaWrite# mwa i l s of
s1 -> go (int2Word# c) (i +# 1#) s1
+-- | Multiply a non-zero BigNat and a non-zero Word#
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a + 1
+--
+-- The potential 0 most-significant Word (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
bignat_mul_word
:: MutableWordArray# RealWorld -- ^ Result
-> WordArray#
@@ -173,6 +209,13 @@ bignat_mul_word mwa wa b = go 0# 0##
s' -> go (i +# 1#) carry' s'
+-- | Multiply two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a+size b
+--
+-- The potential 0 most-significant Word (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
bignat_mul
:: MutableWordArray# RealWorld -- ^ Result
-> WordArray#
@@ -214,6 +257,15 @@ bignat_mul mwa wa wb s1 =
bi -> case mul mwa wa bi i ctzA 0## s of
s' -> mulEachB (i +# 1#) s'
+-- | Sub two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
+--
+-- Return False# to indicate underflow.
bignat_sub
:: MutableWordArray# RealWorld
-> WordArray#
@@ -227,6 +279,7 @@ bignat_sub mwa wa wb s =
case mwaArrayCopy# mwa 0# wa 0# (wordArraySize# wa) s of
s' -> mwaSubInplaceArray mwa 0# wb s'
+-- | PopCount of a non-zero BigNat
bignat_popcount :: WordArray# -> Word#
bignat_popcount wa = go 0# 0##
where
@@ -235,6 +288,13 @@ bignat_popcount wa = go 0# 0##
| isTrue# (i ==# sz) = c
| True = go (i +# 1#) (c `plusWord#` popCnt# (indexWordArray# wa i))
+-- | Left-shift a non-zero BigNat by a non-zero amount of bits
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a + required new limbs
+--
+-- The potential 0 most-significant Word (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
bignat_shiftl
:: MutableWordArray# s
-> WordArray#
@@ -267,6 +327,13 @@ bignat_shiftl mwa wa n s1 =
s' -> mwaBitShift (i +# 1#) c' s'
+-- | Right-shift a non-zero BigNat by a non-zero amount of bits
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: required limbs
+--
+-- The potential 0 most-significant Word (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
bignat_shiftr
:: MutableWordArray# s
-> WordArray#
@@ -293,6 +360,15 @@ bignat_shiftr mwa wa n s1
in case mwaWrite# mwa i v s of
s' -> mwaBitShift (i -# 1#) c' s'
+-- | Right-shift a non-zero BigNat by a non-zero amount of bits by first
+-- converting it into its two's complement representation and then again after
+-- the arithmetic shift.
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: required limbs
+--
+-- The potential 0 most-significant Words (i.e. the potential carry) will be
+-- removed by the caller if it is not already done by the backend.
bignat_shiftr_neg
:: MutableWordArray# s
-> WordArray#
@@ -329,6 +405,10 @@ bignat_shiftr_neg mwa wa n s1
in go 0#
+-- | OR two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: max (size a, size b)
bignat_or
:: MutableWordArray# RealWorld -- ^ Result
-> WordArray#
@@ -346,6 +426,13 @@ bignat_or mwa wa wb s1
case mwaInitArrayBinOp mwa wx wy or# s of
s' -> mwaArrayCopy# mwa ny wx ny (nx -# ny) s'
+-- | XOR two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: max (size a, size b)
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
bignat_xor
:: MutableWordArray# RealWorld -- ^ Result
-> WordArray#
@@ -363,6 +450,13 @@ bignat_xor mwa wa wb s1
case mwaInitArrayBinOp mwa wx wy xor# s of
s' -> mwaArrayCopy# mwa ny wx ny (nx -# ny) s'
+-- | AND two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: min (size a, size b)
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
bignat_and
:: MutableWordArray# RealWorld -- ^ Result
-> WordArray#
@@ -371,6 +465,13 @@ bignat_and
-> State# RealWorld
bignat_and mwa wa wb s = mwaInitArrayBinOp mwa wa wb and# s
+-- | ANDNOT two non-zero BigNat
+--
+-- Result is to be stored in the MutableWordArray#.
+-- The latter has size: size a
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
bignat_and_not
:: MutableWordArray# RealWorld -- ^ Result
-> WordArray#
@@ -384,9 +485,17 @@ bignat_and_not mwa wa wb s =
!szA = wordArraySize# wa
!szB = wordArraySize# wb
+-- | QuotRem of two non-zero BigNat
+--
+-- Result quotient and remainder are to be stored in the MutableWordArray#.
+-- The first one (quotient) has size: size(A)-size(B)+1
+-- The second one (remainder) has size: size(b)
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
bignat_quotrem
- :: MutableWordArray# s
- -> MutableWordArray# s
+ :: MutableWordArray# s -- ^ Quotient
+ -> MutableWordArray# s -- ^ Remainder
-> WordArray#
-> WordArray#
-> State# s
@@ -434,8 +543,15 @@ bignat_quotrem mwq mwr uwa uwb s0 =
+-- | Quotient of two non-zero BigNat
+--
+-- Result quotient is to be stored in the MutableWordArray#.
+-- The latter has size: size(A)-size(B)+1
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
bignat_quot
- :: MutableWordArray# RealWorld
+ :: MutableWordArray# RealWorld -- ^ Quotient
-> WordArray#
-> WordArray#
-> State# RealWorld
@@ -445,8 +561,15 @@ bignat_quot mwq wa wb s =
case newWordArray# (wordArraySize# wb) s of
(# s, mwr #) -> bignat_quotrem mwq mwr wa wb s
+-- | Remainder of two non-zero BigNat
+--
+-- Result remainder is to be stored in the MutableWordArray#.
+-- The latter has size: size(B)
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
bignat_rem
- :: MutableWordArray# RealWorld
+ :: MutableWordArray# RealWorld -- ^ Remainder
-> WordArray#
-> WordArray#
-> State# RealWorld
@@ -577,6 +700,15 @@ bignat_quotrem_normalized mwq mwa b s0 =
| True -> loop (m -# 1#) s2
}}
+-- | QuotRem of a non-zero BigNat and a non-zero Word
+--
+-- Result quotient is to be stored in the MutableWordArray#.
+-- The latter has size: size(A)
+--
+-- The remainder is returned.
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
bignat_quotrem_word
:: MutableWordArray# s -- ^ Quotient
-> WordArray#
@@ -595,6 +727,13 @@ bignat_quotrem_word mwq wa b s = go (sz -# 1#) 0## s
in case mwaWrite# mwq i q s of
s' -> go (i -# 1#) r' s'
+-- | Quot of a non-zero BigNat and a non-zero Word
+--
+-- Result quotient is to be stored in the MutableWordArray#.
+-- The latter has size: size(A)
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
bignat_quot_word
:: MutableWordArray# s -- ^ Quotient
-> WordArray#
@@ -613,6 +752,9 @@ bignat_quot_word mwq wa b s = go (sz -# 1#) 0## s
in case mwaWrite# mwq i q s of
s' -> go (i -# 1#) r' s'
+-- | Remainder of a non-zero BigNat and a non-zero Word
+--
+-- The remainder is returned.
bignat_rem_word
:: WordArray#
-> Word#
@@ -629,6 +771,14 @@ bignat_rem_word wa b = go (sz -# 1#) 0##
in go (i -# 1#) r'
+-- | Greatest common divisor (GCD) of two non-zero and non-one BigNat
+--
+-- Result GCD is to be stored in the MutableWordArray#.
+-- The latter has size: size(B)
+-- The first WordArray# is greater than the second WordArray#.
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
bignat_gcd
:: MutableWordArray# s
-> WordArray#
@@ -647,13 +797,21 @@ bignat_gcd mwr = go
!wmin' = bigNatRem wmax wmin
in go wmax' wmin' s
+-- | Greatest common divisor (GCD) of a non-zero/non-one BigNat and a
+-- non-zero/non-one Word#
+--
+-- Result GCD is returned
bignat_gcd_word
:: WordArray#
-> Word#
-> Word#
bignat_gcd_word a b = bignat_gcd_word_word b (bigNatRemWord# a b)
--- | This operation doesn't really belongs here, but GMP's one is much faster
+-- | Greatest common divisor (GCD) of two Word#
+--
+-- Result GCD is returned.
+--
+-- This operation doesn't really belongs here, but GMP's one is much faster
-- than this simple implementation (basic Euclid algorithm).
--
-- Ideally we should make an implementation as fast as GMP's one and put it into
@@ -665,6 +823,7 @@ bignat_gcd_word_word
bignat_gcd_word_word a 0## = a
bignat_gcd_word_word a b = bignat_gcd_word_word b (a `remWord#` b)
+-- | Encode (# BigNat mantissa, Int# exponent #) into a Double#
bignat_encode_double :: WordArray# -> Int# -> Double#
bignat_encode_double wa e0 = go 0.0## e0 0#
where
@@ -676,6 +835,12 @@ bignat_encode_double wa e0 = go 0.0## e0 0#
(e +# WORD_SIZE_IN_BITS#) -- FIXME: we assume that e doesn't overflow...
(i +# 1#)
+-- | \"@'bignat_powmod_word' /b/ /e/ /m/@\" computes base @/b/@ raised to
+-- exponent @/e/@ modulo @/m/@.
+--
+-- b > 1
+-- e > 0
+-- m > 1
bignat_powmod_word :: WordArray# -> WordArray# -> Word# -> Word#
bignat_powmod_word b0 e0 m = go (naturalFromBigNat# b0) (naturalFromBigNat# e0) (naturalFromWord# 1##)
where
@@ -693,6 +858,18 @@ bignat_powmod_word b0 e0 m = go (naturalFromBigNat# b0) (naturalFromBigNat# e0)
m' = naturalFromWord# m
e' = e `naturalShiftR#` 1## -- slightly faster than "e `div` 2"
+-- | \"@'bignat_powmod' r /b/ /e/ /m/@\" computes base @/b/@ raised to
+-- exponent @/e/@ modulo @/m/@.
+--
+-- b > 1
+-- e > 0
+-- m > 1
+--
+-- Result is to be stored in the MutableWordArray# (which size is equal to the
+-- one of m).
+--
+-- The potential 0 most-significant Words will be removed by the caller if it is
+-- not already done by the backend.
bignat_powmod
:: MutableWordArray# RealWorld
-> WordArray#
@@ -720,6 +897,12 @@ bignat_powmod r b0 e0 m s = mwaInitCopyShrink# r r' s
m' = naturalFromBigNat# m
e' = e `naturalShiftR#` 1## -- slightly faster than "e `div` 2"
+-- | \"@'bignat_powmod' /b/ /e/ /m/@\" computes base @/b/@ raised to
+-- exponent @/e/@ modulo @/m/@.
+--
+-- b > 1
+-- e > 0
+-- m > 1
bignat_powmod_words
:: Word#
-> Word#
@@ -731,6 +914,13 @@ bignat_powmod_words b e m =
m
+-- | Return extended GCD of two non-zero integers.
+--
+-- I.e. integer_gcde a b returns (g,x,y) so that ax + by = g
+--
+-- Input: a and b are non zero.
+-- Output: g must be > 0
+--
integer_gcde
:: Integer
-> Integer
@@ -748,6 +938,12 @@ integer_gcde a b = f (# a,integerOne,integerZero #) (# b,integerZero,integerOne
!(# q, r #) -> f new (# r , old_s `integerSub` (q `integerMul` s)
, old_t `integerSub` (q `integerMul` t) #)
+-- | Computes the modular inverse of two non-zero integers.
+--
+-- I.e. y = integer_recip_mod x m
+-- = x^(-1) `mod` m
+--
+-- with 0 < y < abs m
integer_recip_mod
:: Integer
-> Natural
@@ -763,6 +959,12 @@ integer_recip_mod x m =
-- a `mod` m > 0 because m > 0
| True -> (# | () #)
+-- | Computes the modular exponentiation.
+--
+-- I.e. y = integer_powmod b e m
+-- = b^e `mod` m
+--
+-- with 0 <= y < abs m
integer_powmod
:: Integer
-> Natural
=====================================
libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Selected.hs deleted
=====================================
@@ -1,24 +0,0 @@
-{-# LANGUAGE CPP #-}
-{-# LANGUAGE NoImplicitPrelude #-}
-
--- | Selected backend
---
--- We need this module in addition to GHC.Internal.Bignum.Backend to avoid module loops with
--- Check backend.
-module GHC.Internal.Bignum.Backend.Selected
- ( module Backend
- )
-where
-
-#if defined(BIGNUM_NATIVE)
-import GHC.Internal.Bignum.Backend.Native as Backend
-
-#elif defined(BIGNUM_FFI)
-import GHC.Internal.Bignum.Backend.FFI as Backend
-
-#elif defined(BIGNUM_GMP)
-import GHC.Internal.Bignum.Backend.GMP as Backend
-
-#else
-#error Undefined BigNum backend. Use a flag to select it (e.g. gmp, native, ffi)`
-#endif
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d603477f4cd5dff83d81d8ecef52e21...
--
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/d603477f4cd5dff83d81d8ecef52e21...
You're receiving this email because of your account on gitlab.haskell.org.