Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC

Commits:

29 changed files:

Changes:

  • changelog.d/hadrian-system-cxx-std-lib-25303
    1
    +section: packaging
    
    2
    +synopsis: Fix Hadrian rules for system-cxx-std-lib package dependency
    
    3
    +issues: #25303
    
    4
    +mrs: !16013
    
    5
    +description: {
    
    6
    +  Hadrian's handling of the `system-cxx-std-lib` virtual package has been
    
    7
    +  fixed and made more uniform.
    
    8
    +
    
    9
    +  Previously, `text` had an ad-hoc rule outside of `configurePackage` to
    
    10
    +  declare a dependency on `system-cxx-std-lib`, the dependency was not
    
    11
    +  discovered from cabal files, and the package database was not recached after
    
    12
    +  the `.conf` file was generated.
    
    13
    +
    
    14
    +  The dependency is now read from cabal files via a new
    
    15
    +  `dependsOnSystemCxxStdLib` field in `PackageData`, and the `.conf` file
    
    16
    +  is needed inside `configurePackage` alongside all other package
    
    17
    +  dependencies, consistent with how every other package is handled.
    
    18
    +
    
    19
    +  `shakeVersion` has been bumped to ensure existing build databases are
    
    20
    +  invalidated when upgrading, preventing binary deserialisation errors due to
    
    21
    +  the changed `PackageData` type.
    
    22
    +}

  • changelog.d/remove-bignum-check-backend
    1
    +section: packaging
    
    2
    +synopsis: Remove the Check backend of ghc-bignum
    
    3
    +issues: #27305
    
    4
    +mrs: !16106
    
    5
    +
    
    6
    +description: {
    
    7
    +    The Check backend of ghc-bignum (now part of ghc-internal), which compared
    
    8
    +    the results of the selected backend against the Native backend, has been
    
    9
    +    removed along with the ``bignum-check`` cabal flag and the ``check-``
    
    10
    +    prefix in Hadrian's ``--bignum`` option.
    
    11
    +}

  • changelog.d/remove-bignum-ffi-backend
    1
    +section: packaging
    
    2
    +synopsis: Remove the FFI backend of ghc-bignum
    
    3
    +issues: #27305
    
    4
    +mrs: !16106
    
    5
    +
    
    6
    +description: {
    
    7
    +    The FFI backend of ghc-bignum (now part of ghc-internal) has been removed.
    
    8
    +    It had no known users and was easy to recreate by relinking ghc-internal
    
    9
    +    with a custom backend implementation. As a result, the ``bignum-ffi``
    
    10
    +    cabal flag has been dropped, and selecting the ``ffi`` backend via
    
    11
    +    Hadrian's ``--bignum`` option is no longer supported.
    
    12
    +}

  • hadrian/README.md
    ... ... @@ -101,7 +101,7 @@ Stage2 GHC.
    101 101
     
    
    102 102
     * `--skip-depends`: skips rebuilding Haskell module dependency files.
    
    103 103
     
    
    104
    -* `--bignum={native,gmp,check-gmp,ffi}`: **Deprecated.** Use the `+native_bignum` flavour
    
    104
    +* `--bignum={native,gmp}`: **Deprecated.** Use the `+native_bignum` flavour
    
    105 105
       transformer instead (e.g. `--flavour=default+native_bignum`). When building for the
    
    106 106
       JavaScript target, the native bignum backend is enabled automatically.
    
    107 107
     
    

  • hadrian/doc/user-settings.md
    ... ... @@ -24,10 +24,8 @@ data Flavour = Flavour {
    24 24
         extraArgs :: Args,
    
    25 25
         -- | Build these packages.
    
    26 26
         packages :: Stage -> Action [Package],
    
    27
    -    -- | Bignum backend: 'native', 'gmp', 'ffi', etc.
    
    27
    +    -- | Bignum backend: 'native', 'gmp', etc.
    
    28 28
         bignumBackend :: String,
    
    29
    -    -- | Check selected bignum backend against native backend
    
    30
    -    bignumCheck :: Bool,
    
    31 29
         -- | Build the @text@ package with @simdutf@ support. Disabled by
    
    32 30
         -- default due to packaging difficulties described in #20724.
    
    33 31
         textWithSIMDUTF :: Bool,
    

  • hadrian/src/CommandLine.hs
    1 1
     module CommandLine (
    
    2 2
         optDescrs, cmdLineArgsMap, cmdFlavour, lookupFreeze1, lookupFreeze2, lookupSkipDepends,
    
    3 3
         lookupBignum,
    
    4
    -    cmdBignum, cmdBignumCheck, cmdProgressInfo, cmdCompleteSetting,
    
    4
    +    cmdBignum, cmdProgressInfo, cmdCompleteSetting,
    
    5 5
         cmdDocsArgs, cmdUnitIdHash, lookupBuildRoot, TestArgs(..), TestSpeed(..), defaultTestArgs,
    
    6 6
         cmdPrefix, cmdChangelogVersion, DocArgs(..), defaultDocArgs,
    
    7 7
         cmdKeepResponseFiles
    
    ... ... @@ -32,7 +32,6 @@ data CommandLineArgs = CommandLineArgs
    32 32
         , skipDepends    :: Bool
    
    33 33
         , unitIdHash     :: Bool
    
    34 34
         , bignum         :: Maybe String
    
    35
    -    , bignumCheck    :: Bool
    
    36 35
         , progressInfo   :: ProgressInfo
    
    37 36
         , buildRoot      :: BuildRoot
    
    38 37
         , testArgs       :: TestArgs
    
    ... ... @@ -54,7 +53,6 @@ defaultCommandLineArgs = CommandLineArgs
    54 53
         , skipDepends    = False
    
    55 54
         , unitIdHash     = False
    
    56 55
         , bignum         = Nothing
    
    57
    -    , bignumCheck    = False
    
    58 56
         , progressInfo   = Brief
    
    59 57
         , buildRoot      = BuildRoot "_build"
    
    60 58
         , testArgs       = defaultTestArgs
    
    ... ... @@ -132,10 +130,7 @@ readFlavour ms = Right $ \flags -> flags { flavour = lower <$> ms }
    132 130
     
    
    133 131
     readBignum :: Maybe String -> Either String (CommandLineArgs -> CommandLineArgs)
    
    134 132
     readBignum Nothing   = Right id
    
    135
    -readBignum (Just ms) = Right $ \flags -> case break (== '-') (lower ms) of
    
    136
    -   (backend,"")          -> flags { bignum = Just backend }
    
    137
    -   ("check",'-':backend) -> flags { bignum = Just backend, bignumCheck = True }
    
    138
    -   _                     -> flags { bignum = Just (lower ms) }
    
    133
    +readBignum (Just ms) = Right $ \flags -> flags { bignum = Just (lower ms) }
    
    139 134
     
    
    140 135
     readBuildRoot :: FilePath -> Either String (CommandLineArgs -> CommandLineArgs)
    
    141 136
     readBuildRoot ms =
    
    ... ... @@ -302,7 +297,7 @@ optDescrs =
    302 297
         , Option [] ["skip-depends"] (NoArg readSkipDepends)
    
    303 298
           "Skip rebuilding dependency information."
    
    304 299
         , Option [] ["bignum"] (OptArg readBignum "BACKEND")
    
    305
    -      "Select bignum backend: native, gmp (default), check-gmp (gmp compared to native), ffi."
    
    300
    +      "Select bignum backend: native, gmp (default)."
    
    306 301
         , Option [] ["progress-info"] (ReqArg readProgressInfo "STYLE")
    
    307 302
           "Progress info style (None, Brief, Normal or Unicorn)."
    
    308 303
         , Option [] ["docs"] (ReqArg readDocsArg "TARGET")
    
    ... ... @@ -429,9 +424,6 @@ cmdUnitIdHash = unitIdHash <$> cmdLineArgs
    429 424
     cmdBignum :: Action (Maybe String)
    
    430 425
     cmdBignum = bignum <$> cmdLineArgs
    
    431 426
     
    
    432
    -cmdBignumCheck :: Action Bool
    
    433
    -cmdBignumCheck = bignumCheck <$> cmdLineArgs
    
    434
    -
    
    435 427
     cmdKeepResponseFiles :: Action Bool
    
    436 428
     cmdKeepResponseFiles = keepResponseFiles <$> cmdLineArgs
    
    437 429
     
    

  • hadrian/src/Flavour/Type.hs
    ... ... @@ -19,10 +19,8 @@ data Flavour = Flavour {
    19 19
         extraArgs :: Args,
    
    20 20
         -- | Build these packages.
    
    21 21
         packages :: Stage -> Action [Package],
    
    22
    -    -- | Bignum backend: 'native', 'gmp', 'ffi', etc.
    
    22
    +    -- | Bignum backend: 'native', 'gmp', etc.
    
    23 23
         bignumBackend :: String,
    
    24
    -    -- | Check selected bignum backend against native backend
    
    25
    -    bignumCheck :: Bool,
    
    26 24
         -- | Build the @text@ package with @simdutf@ support. Disabled by
    
    27 25
         -- default due to packaging difficulties described in #20724.
    
    28 26
         textWithSIMDUTF :: Bool,
    

  • hadrian/src/Hadrian/Haskell/Cabal/Parse.hs
    ... ... @@ -81,10 +81,11 @@ parsePackageData pkg = do
    81 81
             sorted  = sort [ C.unPackageName p | C.Dependency p _ _ <- allDeps ]
    
    82 82
             deps    = nubOrd sorted \\ [name]
    
    83 83
             depPkgs = mapMaybe findPackageByName deps
    
    84
    +        cxxStdLib = elem "system-cxx-std-lib" deps
    
    84 85
         return $ PackageData name version
    
    85 86
                              (C.fromShortText (C.synopsis pd))
    
    86 87
                              (C.fromShortText (C.description pd))
    
    87
    -                         depPkgs gpd
    
    88
    +                         depPkgs cxxStdLib gpd
    
    88 89
       where
    
    89 90
         -- Collect an overapproximation of dependencies by ignoring conditionals
    
    90 91
         collectDeps :: Maybe (C.CondTree v [C.Dependency] a) -> [C.Dependency]
    
    ... ... @@ -138,7 +139,9 @@ configurePackage :: Context -> Action ()
    138 139
     configurePackage context@Context {..} = do
    
    139 140
         putProgressInfo $ "| Configure package " ++ quote (pkgName package)
    
    140 141
         gpd     <- pkgGenericDescription package
    
    141
    -    depPkgs <- packageDependencies <$> readPackageData package
    
    142
    +    pd <- readPackageData package
    
    143
    +    let depPkgs = packageDependencies pd
    
    144
    +        needSystemCxxStdLib = dependsOnSystemCxxStdLib pd
    
    142 145
     
    
    143 146
         -- Stage packages are those we have in this stage.
    
    144 147
         stagePkgs <- stagePackages stage
    
    ... ... @@ -157,7 +160,12 @@ configurePackage context@Context {..} = do
    157 160
         -- We'll need those packages in our package database.
    
    158 161
         deps <- sequence [ pkgConfFile (context { package = pkg, iplace = forceBaseAfterGhcInternal pkg })
    
    159 162
                          | pkg <- depPkgs, pkg `elem` stagePkgs ]
    
    160
    -    need $ extraPreConfigureDeps ++ deps
    
    163
    +    -- system-cxx-std-lib is magic.. it doesn't have a cabal file or source code, so we have
    
    164
    +    -- to treat it specially as `pkgConfFile` uses `readPackageData` to compute the version.
    
    165
    +    systemCxxStdLib <- sequence [ systemCxxStdLibConfPath (PackageDbLoc stage iplace) | needSystemCxxStdLib ]
    
    166
    +    need $ extraPreConfigureDeps
    
    167
    +            ++ deps
    
    168
    +            ++ systemCxxStdLib
    
    161 169
     
    
    162 170
         -- Figure out what hooks we need.
    
    163 171
         let configureFile = replaceFileName (pkgCabalFile package) "configure"
    

  • hadrian/src/Hadrian/Haskell/Cabal/Type.hs
    ... ... @@ -30,6 +30,7 @@ data PackageData = PackageData
    30 30
         , synopsis                  :: String
    
    31 31
         , description               :: String
    
    32 32
         , packageDependencies       :: [Package]
    
    33
    +    , dependsOnSystemCxxStdLib  :: Bool
    
    33 34
         , genericPackageDescription :: GenericPackageDescription
    
    34 35
         } deriving (Eq, Generic, Show)
    
    35 36
     
    

  • hadrian/src/Main.hs
    ... ... @@ -63,7 +63,13 @@ main = do
    63 63
         shakeColor <- shouldUseColor
    
    64 64
         let options :: ShakeOptions
    
    65 65
             options = shakeOptions
    
    66
    -            { shakeChange   = ChangeModtimeAndDigest
    
    66
    +            { -- Bump shakeVersion whenever a type stored in the Shake oracle
    
    67
    +              -- changes its Binary representation (e.g. fields added/removed
    
    68
    +              -- from PackageData or other oracle value types). This forces
    
    69
    +              -- Shake to wipe the stale database instead of crashing on
    
    70
    +              -- deserialisation.
    
    71
    +              shakeVersion  = "2"
    
    72
    +            , shakeChange   = ChangeModtimeAndDigest
    
    67 73
                 , shakeFiles    = buildRoot -/- Base.shakeFilesDir
    
    68 74
                 , shakeProgress = Progress.hadrianProgress cwd
    
    69 75
                 , shakeRebuild  = rebuild
    

  • hadrian/src/Rules/Generate.hs
    ... ... @@ -242,9 +242,6 @@ copyRules = do
    242 242
             prefix -/- "html/**"           <~ return "utils/haddock/haddock-api/resources"
    
    243 243
             prefix -/- "latex/**"          <~ return "utils/haddock/haddock-api/resources"
    
    244 244
     
    
    245
    -        forM_ [Inplace, Final] $ \iplace ->
    
    246
    -          root -/- relativePackageDbPath (PackageDbLoc stage iplace) -/- systemCxxStdLibConf %> \file -> do
    
    247
    -            copyFile ("mk" -/- "system-cxx-std-lib-1.0.conf") file
    
    248 245
     
    
    249 246
     generateRules :: Rules ()
    
    250 247
     generateRules = do
    
    ... ... @@ -390,7 +387,6 @@ templateRules = do
    390 387
         , interpolateSetting "ProjectPatchLevel1" ProjectPatchLevel1
    
    391 388
         , interpolateSetting "ProjectPatchLevel2" ProjectPatchLevel2
    
    392 389
         ]
    
    393
    -  templateRule "rts/win32/libHSghc-internal.def" projectVersion
    
    394 390
       templateRule "docs/index.html" $ packageUnitIds Stage1
    
    395 391
       templateRule "docs/users_guide/ghc_config.py" $ mconcat
    
    396 392
         [ projectVersion
    

  • hadrian/src/Rules/Library.hs
    ... ... @@ -9,6 +9,7 @@ import GHC.Toolchain.Target (Target(tgtArchOs))
    9 9
     
    
    10 10
     import Base
    
    11 11
     import Context
    
    12
    +import qualified Data.List as List
    
    12 13
     import Expression hiding (way, package, stage)
    
    13 14
     import Oracles.ModuleFiles
    
    14 15
     import Packages
    
    ... ... @@ -20,6 +21,7 @@ import Utilities
    20 21
     import Data.Time.Clock
    
    21 22
     import Rules.Generate (generatedDependencies)
    
    22 23
     import Oracles.Flag
    
    24
    +import Way.Type (wayToUnits)
    
    23 25
     
    
    24 26
     
    
    25 27
     -- * Library 'Rules'
    
    ... ... @@ -203,13 +205,32 @@ extraObjects context
    203 205
     
    
    204 206
         | package context == rts = do
    
    205 207
               target   <- interpretInContext context getStagedTarget
    
    206
    -          builddir <- buildPath context
    
    207
    -          return [ builddir -/- "libHSghc-internal.dll.a"
    
    208
    -                 | archOS_OS (tgtArchOs target) == OSMinGW32
    
    209
    -                 , Dynamic `wayUnit` way context ]
    
    208
    +          if not (archOS_OS (tgtArchOs target) == OSMinGW32
    
    209
    +                && Dynamic `wayUnit` way context)
    
    210
    +          then return []
    
    211
    +          else do
    
    212
    +            -- Find the ghc-internal library file name. Note that the
    
    213
    +            -- ghc-internal's .dll.a file is placed in the RTS build dir and not
    
    214
    +            -- the ghc-internal build dir as we only use it when building the
    
    215
    +            -- RTS and not other libraries.
    
    216
    +            ghcInternalDllName <- takeFileName <$> pkgLibraryFile Context {
    
    217
    +                    stage = stage context,
    
    218
    +                    way = rtsWayToLibraryWay (way context),
    
    219
    +                    iplace = iplace context,
    
    220
    +                    package = ghcInternal
    
    221
    +                }
    
    222
    +
    
    223
    +            builddir <- buildPath context
    
    224
    +            return [ builddir -/- ghcInternalDllName <> ".a"]
    
    210 225
     
    
    211 226
         | otherwise = return []
    
    212 227
     
    
    228
    +-- | The rts is compiled in many different ways, but libraries are only built in
    
    229
    +-- (non)Dynamic and (non)Profiled ways. This function converts the rts way into
    
    230
    +-- compatible library way.
    
    231
    +rtsWayToLibraryWay :: Way -> Way
    
    232
    +rtsWayToLibraryWay = wayFromUnits . List.intersect [Dynamic, Profiling] . wayToUnits
    
    233
    +
    
    213 234
     -- | Return all the object files to be put into the library we're building for
    
    214 235
     -- the given 'Context'.
    
    215 236
     libraryObjects :: Context -> Action [FilePath]
    

  • hadrian/src/Rules/Register.hs
    ... ... @@ -6,7 +6,6 @@ module Rules.Register (
    6 6
     
    
    7 7
     import Base
    
    8 8
     import Context
    
    9
    -import Flavour
    
    10 9
     import Oracles.Setting
    
    11 10
     import Hadrian.BuildPath
    
    12 11
     import Hadrian.Expression
    
    ... ... @@ -48,14 +47,6 @@ configurePackageRules = do
    48 47
               isGmp <- (== "gmp") <$> interpretInContext ctx getBignumBackend
    
    49 48
               when isGmp $
    
    50 49
                 need [buildP -/- "include/ghc-gmp.h"]
    
    51
    -        when (pkg == text) $ do
    
    52
    -          simdutf <- textWithSIMDUTF <$> flavour
    
    53
    -          when simdutf $ do
    
    54
    -            -- This is required, otherwise you get Error: hadrian:
    
    55
    -            -- Encountered missing or private dependencies:
    
    56
    -            -- system-cxx-std-lib ==1.0
    
    57
    -            cxxStdLib <- systemCxxStdLibConfPath $ PackageDbLoc stage Inplace
    
    58
    -            need [cxxStdLib]
    
    59 50
             Cabal.configurePackage ctx
    
    60 51
     
    
    61 52
         root -/- "**/autogen/cabal_macros.h" %> \out -> do
    
    ... ... @@ -105,6 +96,12 @@ registerPackageRules rs stage iplace = do
    105 96
                 target (Context stage compiler vanilla iplace) (GhcPkg Recache stage) [] []
    
    106 97
             writeFileLines stamp []
    
    107 98
     
    
    99
    +    -- Special rule for registering system-cxx-std-lib
    
    100
    +    root -/- relativePackageDbPath (PackageDbLoc stage iplace) -/- systemCxxStdLibConf %> \file -> do
    
    101
    +        copyFile ("mk" -/- "system-cxx-std-lib-1.0.conf") file
    
    102
    +        buildWithResources rs $
    
    103
    +            target (Context stage compiler vanilla iplace) (GhcPkg Recache stage) [] []
    
    104
    +
    
    108 105
         -- Register a package.
    
    109 106
         root -/- relativePackageDbPath (PackageDbLoc stage iplace) -/- "*.conf" %> \conf -> do
    
    110 107
             historyDisable
    

  • hadrian/src/Rules/Rts.hs
    ... ... @@ -13,11 +13,19 @@ rtsRules = priority 3 $ do
    13 13
         -- to be linked into the rts dll.
    
    14 14
         forM_ [Stage1, Stage2, Stage3 ] $ \ stage -> do
    
    15 15
             let buildPath = root -/- buildDir (rtsContext stage)
    
    16
    -        buildPath -/- "libHSghc-internal.dll.a" %> buildGhcInternalImportLib
    
    16
    +        buildPath -/- "libHSghc-internal-*.def" %> buildGhcInternalImportDef
    
    17
    +        buildPath -/- "libHSghc-internal-*.dll.a" %> buildGhcInternalImportLib
    
    18
    +
    
    19
    +buildGhcInternalImportDef :: FilePath -> Action ()
    
    20
    +buildGhcInternalImportDef target = do
    
    21
    +    templateIn <- readFile' "rts/win32/libHSghc-internal.def.in"
    
    22
    +    let dllName = takeFileName target -<.> "dll"
    
    23
    +        templateOut = replace "@GhcInternalDll@" dllName templateIn
    
    24
    +    writeFile' target templateOut
    
    17 25
     
    
    18 26
     buildGhcInternalImportLib :: FilePath -> Action ()
    
    19 27
     buildGhcInternalImportLib target = do
    
    20
    -    let input  = "rts/win32/libHSghc-internal.def"
    
    28
    +    let input = dropExtensions target <.> "def" -- the .def file
    
    21 29
             output = target -- the .dll.a import lib
    
    22 30
         need [input]
    
    23 31
         runBuilder Dlltool ["-d", input, "-l", output] [input] [output]

  • hadrian/src/Settings.hs
    ... ... @@ -3,7 +3,7 @@
    3 3
     module Settings (
    
    4 4
         getExtraArgs, getArgs, getLibraryWays, getRtsWays, flavour, knownPackages,
    
    5 5
         findPackageByName, unsafeFindPackageByName, unsafeFindPackageByPath,
    
    6
    -    isLibrary, stagePackages, getBignumBackend, getBignumCheck, completeSetting,
    
    6
    +    isLibrary, stagePackages, getBignumBackend, completeSetting,
    
    7 7
         queryBuildTarget, queryHostTarget, queryTargetTarget,
    
    8 8
         queryBuild, queryHost, queryTarget,
    
    9 9
         queryArch, queryOS, queryVendor
    
    ... ... @@ -46,11 +46,6 @@ getRtsWays = expr flavour >>= rtsWays
    46 46
     getBignumBackend :: Expr String
    
    47 47
     getBignumBackend = bignumBackend <$> expr flavour
    
    48 48
     
    
    49
    -getBignumCheck :: Expr Bool
    
    50
    -getBignumCheck = expr $ cmdBignum >>= \case
    
    51
    -   Nothing -> bignumCheck <$> flavour
    
    52
    -   Just _  -> cmdBignumCheck
    
    53
    -
    
    54 49
     stagePackages :: Stage -> Action [Package]
    
    55 50
     stagePackages stage = do
    
    56 51
         f <- flavour
    

  • hadrian/src/Settings/Builders/RunTest.hs
    ... ... @@ -241,7 +241,6 @@ runTestBuilderArgs = builder Testsuite ? do
    241 241
     
    
    242 242
         -- MP: TODO, these should be queried from the test compiler?
    
    243 243
         bignumBackend <- getBignumBackend
    
    244
    -    bignumCheck   <- getBignumCheck
    
    245 244
     
    
    246 245
         keepFiles <- expr (testKeepFiles <$> userSetting defaultTestArgs)
    
    247 246
     
    
    ... ... @@ -307,7 +306,7 @@ runTestBuilderArgs = builder Testsuite ? do
    307 306
                 , arg "-e", arg $ "ghc_compiler_always_flags=" ++ quote ghcFlags
    
    308 307
                 , arg "-e", arg $ asBool "ghc_with_dynamic_rts="  (hasDynamicRts)
    
    309 308
                 , arg "-e", arg $ asBool "config.ghc_with_threaded_rts=" (hasThreadedRts)
    
    310
    -            , arg "-e", arg $ asBool "config.have_fast_bignum=" (bignumBackend /= "native" && not bignumCheck)
    
    309
    +            , arg "-e", arg $ asBool "config.have_fast_bignum=" (bignumBackend /= "native")
    
    311 310
                 , arg "-e", arg $ asBool "config.target_has_smp=" targetWithSMP
    
    312 311
                 , arg "-e", arg $ "config.ghc_dynamic=" ++ show hasDynamic
    
    313 312
                 , arg "-e", arg $ "config.leading_underscore=" ++ show leadingUnderscore
    

  • hadrian/src/Settings/Default.hs
    ... ... @@ -293,7 +293,6 @@ defaultFlavour = Flavour
    293 293
         , extraArgs          = defaultExtraArgs
    
    294 294
         , packages           = defaultPackages
    
    295 295
         , bignumBackend      = defaultBignumBackend
    
    296
    -    , bignumCheck        = False
    
    297 296
         , textWithSIMDUTF    = False
    
    298 297
         , libraryWays        = defaultLibraryWays
    
    299 298
         , rtsWays            = defaultRtsWays
    

  • hadrian/src/Settings/Packages.hs
    ... ... @@ -240,15 +240,11 @@ ghcInternalArgs = package ghcInternal ? do
    240 240
         includesGmp <- getSetting GmpIncludeDir
    
    241 241
     
    
    242 242
         backend <- getBignumBackend
    
    243
    -    check   <- getBignumCheck
    
    244 243
     
    
    245 244
         mconcat
    
    246 245
               [ -- select bignum backend
    
    247 246
                 builder (Cabal Flags) ? arg ("bignum-" <> backend)
    
    248 247
     
    
    249
    -          , -- check the selected backend against native backend
    
    250
    -            builder (Cabal Flags) ? check `cabalFlag` "bignum-check"
    
    251
    -
    
    252 248
                 -- backend specific
    
    253 249
               , case backend of
    
    254 250
                    "gmp" -> mconcat
    

  • libraries/ghc-bignum/ghc-bignum.cabal
    ... ... @@ -36,7 +36,7 @@ library
    36 36
           GHC.Internal.Bignum.Primitives       as GHC.Num.Primitives
    
    37 37
         , GHC.Internal.Bignum.WordArray        as GHC.Num.WordArray
    
    38 38
         , GHC.Internal.Bignum.Backend          as GHC.Num.Backend
    
    39
    -    , GHC.Internal.Bignum.Backend.Selected as GHC.Num.Backend.Selected
    
    39
    +    , GHC.Internal.Bignum.Backend          as GHC.Num.Backend.Selected
    
    40 40
         , GHC.Internal.Bignum.Backend.Native   as GHC.Num.Backend.Native
    
    41 41
         , GHC.Internal.Bignum.BigNat           as GHC.Num.BigNat
    
    42 42
         , GHC.Internal.Bignum.Natural          as GHC.Num.Natural
    

  • libraries/ghc-internal/bignum-backend.rst
    ... ... @@ -33,20 +33,9 @@ supported:
    33 33
       integer-simple package. The major difference is that it uses a much more
    
    34 34
       efficient memory representation (integer-simple was based on Haskell lists)
    
    35 35
       and that it allows a lot more code sharing between the different backends than
    
    36
    -  was previously possible between integer-gmp and integer-simple.
    
    37
    -
    
    38
    -* FFI: an implementation that relies on external FFI calls. This backend can be
    
    39
    -  useful:
    
    40
    -
    
    41
    -  * for alternative GHC backends that target non native platforms (JavaScript,
    
    42
    -    JVM, etc.): the backend can dynamically match and rewrite the FFI calls in
    
    43
    -    order to call the appropriate platform specific BigNum API.
    
    44
    -    
    
    45
    -  * to test new native backends: just tweak the ghc-bignum build to link with
    
    46
    -    the native library providing the implementation of the FFI calls
    
    47
    -
    
    48
    -  Note that the FFI backend module contains the description of the interface
    
    49
    -  that needs to be implemented by every backend.
    
    36
    +  was previously possible between integer-gmp and integer-simple. The Native
    
    37
    +  backend module contains the description of the interface that needs to be
    
    38
    +  implemented by every backend.
    
    50 39
     
    
    51 40
     This package has been designed to make the implementation of new backends
    
    52 41
     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
    56 56
         Manual: True
    
    57 57
         Default: False
    
    58 58
     
    
    59
    -Flag bignum-ffi
    
    60
    -    Description: Enable FFI bignum backend
    
    61
    -    Manual: True
    
    62
    -    Default: False
    
    63
    -
    
    64 59
     Flag bignum-gmp
    
    65 60
         Description: Enable GMP bignum backend
    
    66 61
         Manual: True
    
    67 62
         Default: False
    
    68 63
     
    
    69
    -Flag bignum-check
    
    70
    -    Description: Validate results of the enabled backend against native backend.
    
    71
    -    Manual: True
    
    72
    -    Default: False
    
    73
    -
    
    74 64
     Flag need-atomic
    
    75 65
         Description: Enable linking with "atomic" library (for 64-bit atomic ops on armel, #20549)
    
    76 66
         Manual: True
    
    ... ... @@ -382,13 +372,11 @@ Library
    382 372
         -- Bignum configuration
    
    383 373
         ----------------------------------------
    
    384 374
         -- check that at least one backend is enabled
    
    385
    -    if !flag(bignum-native) && !flag(bignum-gmp) && !flag(bignum-ffi)
    
    375
    +    if !flag(bignum-native) && !flag(bignum-gmp)
    
    386 376
           buildable: False
    
    387 377
     
    
    388 378
         -- check that at most one flag is set
    
    389
    -    if flag(bignum-native) && (flag(bignum-gmp) || flag(bignum-ffi))
    
    390
    -      buildable: False
    
    391
    -    if flag(bignum-gmp) && flag(bignum-ffi)
    
    379
    +    if flag(bignum-native) && flag(bignum-gmp)
    
    392 380
           buildable: False
    
    393 381
     
    
    394 382
         if flag(bignum-gmp)
    
    ... ... @@ -398,25 +386,14 @@ Library
    398 386
             c-sources:
    
    399 387
                cbits/gmp_wrappers.c
    
    400 388
     
    
    401
    -    if flag(bignum-ffi)
    
    402
    -        cpp-options: -DBIGNUM_FFI
    
    403
    -        other-modules:
    
    404
    -           GHC.Internal.Bignum.Backend.FFI
    
    405
    -
    
    406 389
         if flag(bignum-native)
    
    407 390
             cpp-options: -DBIGNUM_NATIVE
    
    408 391
     
    
    409
    -    if flag(bignum-check)
    
    410
    -        cpp-options: -DBIGNUM_CHECK
    
    411
    -        other-modules:
    
    412
    -           GHC.Internal.Bignum.Backend.Check
    
    413
    -
    
    414 392
         exposed-modules:
    
    415 393
           GHC.Internal.Bignum.Primitives
    
    416 394
           GHC.Internal.Bignum.WordArray
    
    417 395
           GHC.Internal.Bignum.BigNat
    
    418 396
           GHC.Internal.Bignum.Backend
    
    419
    -      GHC.Internal.Bignum.Backend.Selected
    
    420 397
           GHC.Internal.Bignum.Backend.Native
    
    421 398
           GHC.Internal.Bignum.Natural
    
    422 399
           GHC.Internal.Bignum.Integer
    

  • libraries/ghc-internal/src/GHC/Internal/Bignum/Backend.hs
    ... ... @@ -7,9 +7,12 @@ module GHC.Internal.Bignum.Backend
    7 7
        )
    
    8 8
     where
    
    9 9
     
    
    10
    -#if defined(BIGNUM_CHECK)
    
    11
    -import GHC.Internal.Bignum.Backend.Check    as Backend
    
    10
    +#if defined(BIGNUM_NATIVE)
    
    11
    +import GHC.Internal.Bignum.Backend.Native as Backend
    
    12
    +
    
    13
    +#elif defined(BIGNUM_GMP)
    
    14
    +import GHC.Internal.Bignum.Backend.GMP as Backend
    
    15
    +
    
    12 16
     #else
    
    13
    -import GHC.Internal.Bignum.Backend.Selected as Backend
    
    17
    +#error Undefined BigNum backend. Use a flag to select it (e.g. gmp, native)`
    
    14 18
     #endif
    15
    -

  • libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Check.hs deleted
    1
    -{-# LANGUAGE CPP #-}
    
    2
    -{-# LANGUAGE NoImplicitPrelude #-}
    
    3
    -{-# LANGUAGE BangPatterns #-}
    
    4
    -{-# LANGUAGE GHCForeignImportPrim #-}
    
    5
    -{-# LANGUAGE MagicHash #-}
    
    6
    -{-# LANGUAGE UnboxedTuples #-}
    
    7
    -{-# LANGUAGE UnliftedFFITypes #-}
    
    8
    -{-# LANGUAGE NegativeLiterals #-}
    
    9
    -{-# LANGUAGE ForeignFunctionInterface #-}
    
    10
    -{-# OPTIONS_GHC -Wno-name-shadowing #-}
    
    11
    -
    
    12
    --- | Check Native implementation against another backend
    
    13
    -module GHC.Internal.Bignum.Backend.Check where
    
    14
    -
    
    15
    -import GHC.Internal.CString
    
    16
    -import GHC.Internal.Prim
    
    17
    -import GHC.Internal.Types
    
    18
    -import GHC.Internal.Bignum.WordArray
    
    19
    -import GHC.Internal.Bignum.Primitives
    
    20
    -import {-# SOURCE #-} GHC.Internal.Bignum.Integer
    
    21
    -import {-# SOURCE #-} GHC.Internal.Bignum.Natural
    
    22
    -import qualified GHC.Internal.Bignum.Backend.Native   as Native
    
    23
    -import qualified GHC.Internal.Bignum.Backend.Selected as Other
    
    24
    -
    
    25
    -#if defined(BIGNUM_NATIVE)
    
    26
    -#error You can't validate Native backend against itself. Choose another backend (e.g. gmp, ffi)
    
    27
    -#endif
    
    28
    -
    
    29
    -default ()
    
    30
    -
    
    31
    --- | ghc-bignum backend name
    
    32
    -backendName :: [Char]
    
    33
    -backendName = unpackAppendCString# "check-"# Other.backendName
    
    34
    -  -- we don't have (++) at our disposal, so we directly use
    
    35
    -  -- `unpackAppendCString#`
    
    36
    -
    
    37
    -bignat_compare
    
    38
    -   :: WordArray#
    
    39
    -   -> WordArray#
    
    40
    -   -> Int#
    
    41
    -bignat_compare a b =
    
    42
    -   let
    
    43
    -      gr = Other.bignat_compare a b
    
    44
    -      nr = Native.bignat_compare a b
    
    45
    -   in case gr ==# nr of
    
    46
    -         0# -> unexpectedValue_Int# (# #)
    
    47
    -         _  -> gr
    
    48
    -
    
    49
    -mwaCompare
    
    50
    -   :: MutableWordArray# s
    
    51
    -   -> MutableWordArray# s
    
    52
    -   -> State# s
    
    53
    -   -> (# State# s, Bool# #)
    
    54
    -mwaCompare mwa mwb s =
    
    55
    -   case mwaSize# mwa s of
    
    56
    -      (# s, szA #) -> case mwaSize# mwb s of
    
    57
    -         (# s, szB #) -> case szA ==# szB of
    
    58
    -            0# -> (# s, 0# #)
    
    59
    -            _  -> let
    
    60
    -                     go i s
    
    61
    -                        | isTrue# (i <# 0#) = (# s, 1# #)
    
    62
    -                        | True =
    
    63
    -                           case readWordArray# mwa i s of
    
    64
    -                              (# s, a #) -> case readWordArray# mwb i s of
    
    65
    -                                 (# s, b #) -> case a `eqWord#` b of
    
    66
    -                                    0# -> (# s, 0# #)
    
    67
    -                                    _  -> go (i -# 1#) s
    
    68
    -                  in go (szA -# 1#) s
    
    69
    -
    
    70
    -mwaCompareOp
    
    71
    -   :: MutableWordArray# s
    
    72
    -   -> (MutableWordArray# s -> State# s -> State# s)
    
    73
    -   -> (MutableWordArray# s -> State# s -> State# s)
    
    74
    -   -> State# s
    
    75
    -   -> State# s
    
    76
    -mwaCompareOp mwa f g s =
    
    77
    -   case mwaSize# mwa s of { (# s, sz #) ->
    
    78
    -   case newWordArray# sz s of { (# s, mwb #) ->
    
    79
    -   case f mwa s of { s ->
    
    80
    -   case g mwb s of { s ->
    
    81
    -   case mwaTrimZeroes# mwa s of { s ->
    
    82
    -   case mwaTrimZeroes# mwb s of { s ->
    
    83
    -   case mwaCompare mwa mwb s of
    
    84
    -      (# s, 0# #) -> case unexpectedValue of
    
    85
    -                        !_ -> s
    
    86
    -                        -- see Note [ghc-bignum exceptions] in
    
    87
    -                        -- GHC.Num.Primitives
    
    88
    -      (# s, _  #) -> s
    
    89
    -   }}}}}}
    
    90
    -
    
    91
    -mwaCompareOp2
    
    92
    -   :: MutableWordArray# s
    
    93
    -   -> MutableWordArray# s
    
    94
    -   -> (MutableWordArray# s -> MutableWordArray# s -> State# s -> State# s)
    
    95
    -   -> (MutableWordArray# s -> MutableWordArray# s -> State# s -> State# s)
    
    96
    -   -> State# s
    
    97
    -   -> State# s
    
    98
    -mwaCompareOp2 mwa mwb f g s =
    
    99
    -   case mwaSize# mwa s of { (# s, szA #) ->
    
    100
    -   case mwaSize# mwb s of { (# s, szB #) ->
    
    101
    -   case newWordArray# szA s of { (# s, mwa' #) ->
    
    102
    -   case newWordArray# szB s of { (# s, mwb' #) ->
    
    103
    -   case f mwa  mwb  s of { s ->
    
    104
    -   case g mwa' mwb' s of { s ->
    
    105
    -   case mwaTrimZeroes# mwa s of { s ->
    
    106
    -   case mwaTrimZeroes# mwb s of { s ->
    
    107
    -   case mwaTrimZeroes# mwa' s of { s ->
    
    108
    -   case mwaTrimZeroes# mwb' s of { s ->
    
    109
    -   case mwaCompare mwa mwa' s of { (# s, ba #) ->
    
    110
    -   case mwaCompare mwb mwb' s of { (# s, bb #) ->
    
    111
    -   case ba &&# bb of
    
    112
    -      0# -> case unexpectedValue of
    
    113
    -               !_ -> s
    
    114
    -               -- see Note [ghc-bignum exceptions] in GHC.Num.Primitives
    
    115
    -      _  -> s
    
    116
    -   }}}}}}}}}}}}
    
    117
    -
    
    118
    -mwaCompareOpBool
    
    119
    -   :: MutableWordArray# s
    
    120
    -   -> (MutableWordArray# s -> State# s -> (#State# s, Bool# #))
    
    121
    -   -> (MutableWordArray# s -> State# s -> (#State# s, Bool# #))
    
    122
    -   -> State# s
    
    123
    -   -> (# State# s, Bool# #)
    
    124
    -mwaCompareOpBool mwa f g s =
    
    125
    -   case mwaSize# mwa s of { (# s, sz #) ->
    
    126
    -   case newWordArray# sz s of { (# s, mwb #) ->
    
    127
    -   case f mwa s of { (# s, ra #) ->
    
    128
    -   case g mwb s of { (# s, rb #) ->
    
    129
    -   case ra ==# rb of
    
    130
    -      0# -> case unexpectedValue of
    
    131
    -               !_ -> (# s, ra #)
    
    132
    -               -- see Note [ghc-bignum exceptions] in GHC.Num.Primitives
    
    133
    -      _  -> case ra of -- don't compare MWAs if underflow signaled!
    
    134
    -         0# -> (# s, ra #) -- underflow
    
    135
    -         _  -> case mwaTrimZeroes# mwa s of { s ->
    
    136
    -               case mwaTrimZeroes# mwb s of { s ->
    
    137
    -               case mwaCompare mwa mwb s of
    
    138
    -                  (# s, 0# #) -> case unexpectedValue of
    
    139
    -                                    !_ -> (# s, ra #)
    
    140
    -                                    -- see Note [ghc-bignum exceptions] in
    
    141
    -                                    -- GHC.Num.Primitives
    
    142
    -                  _  -> (# s, ra #)
    
    143
    -   }}}}}}
    
    144
    -
    
    145
    -mwaCompareOpWord
    
    146
    -   :: MutableWordArray# s
    
    147
    -   -> (MutableWordArray# s -> State# s -> (#State# s, Word# #))
    
    148
    -   -> (MutableWordArray# s -> State# s -> (#State# s, Word# #))
    
    149
    -   -> State# s
    
    150
    -   -> (# State# s, Word# #)
    
    151
    -mwaCompareOpWord mwa f g s =
    
    152
    -   case mwaSize# mwa s of { (# s, sz #) ->
    
    153
    -   case newWordArray# sz s of { (# s, mwb #) ->
    
    154
    -   case f mwa s of { (# s, ra #) ->
    
    155
    -   case g mwb s of { (# s, rb #) ->
    
    156
    -   case mwaTrimZeroes# mwa s of { s ->
    
    157
    -   case mwaTrimZeroes# mwb s of { s ->
    
    158
    -   case mwaCompare mwa mwb s of
    
    159
    -      (# s, b #) -> case b &&# (ra `eqWord#` rb) of
    
    160
    -         0# -> case unexpectedValue of
    
    161
    -                  !_ -> (# s, ra #)
    
    162
    -                  -- see Note [ghc-bignum exceptions] in GHC.Num.Primitives
    
    163
    -         _  -> (# s, ra #)
    
    164
    -   }}}}}}
    
    165
    -
    
    166
    -bignat_add
    
    167
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    168
    -   -> WordArray#
    
    169
    -   -> WordArray#
    
    170
    -   -> State# RealWorld
    
    171
    -   -> State# RealWorld
    
    172
    -bignat_add mwa wa wb
    
    173
    -   = mwaCompareOp mwa
    
    174
    -      (\m -> Other.bignat_add m wa wb)
    
    175
    -      (\m -> Native.bignat_add m wa wb)
    
    176
    -
    
    177
    -bignat_add_word
    
    178
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    179
    -   -> WordArray#
    
    180
    -   -> Word#
    
    181
    -   -> State# RealWorld
    
    182
    -   -> State# RealWorld
    
    183
    -bignat_add_word mwa wa b
    
    184
    -   = mwaCompareOp mwa
    
    185
    -      (\m -> Other.bignat_add_word m wa b)
    
    186
    -      (\m -> Native.bignat_add_word m wa b)
    
    187
    -
    
    188
    -bignat_mul_word
    
    189
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    190
    -   -> WordArray#
    
    191
    -   -> Word#
    
    192
    -   -> State# RealWorld
    
    193
    -   -> State# RealWorld
    
    194
    -bignat_mul_word mwa wa b
    
    195
    -   = mwaCompareOp mwa
    
    196
    -      (\m -> Other.bignat_mul_word m wa b)
    
    197
    -      (\m -> Native.bignat_mul_word m wa b)
    
    198
    -
    
    199
    -bignat_sub
    
    200
    -   :: MutableWordArray# RealWorld
    
    201
    -   -> WordArray#
    
    202
    -   -> WordArray#
    
    203
    -   -> State# RealWorld
    
    204
    -   -> (# State# RealWorld, Bool# #)
    
    205
    -bignat_sub mwa wa wb
    
    206
    -   = mwaCompareOpBool mwa
    
    207
    -      (\m -> Other.bignat_sub m wa wb)
    
    208
    -      (\m -> Native.bignat_sub m wa wb)
    
    209
    -
    
    210
    -bignat_sub_word
    
    211
    -   :: MutableWordArray# RealWorld
    
    212
    -   -> WordArray#
    
    213
    -   -> Word#
    
    214
    -   -> State# RealWorld
    
    215
    -   -> (# State# RealWorld, Bool# #)
    
    216
    -bignat_sub_word mwa wa b
    
    217
    -   = mwaCompareOpBool mwa
    
    218
    -      (\m -> Other.bignat_sub_word m wa b)
    
    219
    -      (\m -> Native.bignat_sub_word m wa b)
    
    220
    -
    
    221
    -bignat_mul
    
    222
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    223
    -   -> WordArray#
    
    224
    -   -> WordArray#
    
    225
    -   -> State# RealWorld
    
    226
    -   -> State# RealWorld
    
    227
    -bignat_mul mwa wa wb
    
    228
    -   = mwaCompareOp mwa
    
    229
    -      (\m -> Other.bignat_mul m wa wb)
    
    230
    -      (\m -> Native.bignat_mul m wa wb)
    
    231
    -
    
    232
    -bignat_popcount :: WordArray# -> Word#
    
    233
    -bignat_popcount wa =
    
    234
    -   let
    
    235
    -      gr = Other.bignat_popcount wa
    
    236
    -      nr = Native.bignat_popcount wa
    
    237
    -   in case gr `eqWord#` nr of
    
    238
    -         0# -> 1## `quotWord#` 0##
    
    239
    -         _  -> gr
    
    240
    -
    
    241
    -bignat_shiftl
    
    242
    -   :: MutableWordArray# RealWorld
    
    243
    -   -> WordArray#
    
    244
    -   -> Word#
    
    245
    -   -> State# RealWorld
    
    246
    -   -> State# RealWorld
    
    247
    -bignat_shiftl mwa wa n
    
    248
    -   = mwaCompareOp mwa
    
    249
    -      (\m -> Other.bignat_shiftl m wa n)
    
    250
    -      (\m -> Native.bignat_shiftl m wa n)
    
    251
    -
    
    252
    -bignat_shiftr
    
    253
    -   :: MutableWordArray# RealWorld
    
    254
    -   -> WordArray#
    
    255
    -   -> Word#
    
    256
    -   -> State# RealWorld
    
    257
    -   -> State# RealWorld
    
    258
    -bignat_shiftr mwa wa n
    
    259
    -   = mwaCompareOp mwa
    
    260
    -      (\m -> Other.bignat_shiftr m wa n)
    
    261
    -      (\m -> Native.bignat_shiftr m wa n)
    
    262
    -
    
    263
    -bignat_shiftr_neg
    
    264
    -   :: MutableWordArray# RealWorld
    
    265
    -   -> WordArray#
    
    266
    -   -> Word#
    
    267
    -   -> State# RealWorld
    
    268
    -   -> State# RealWorld
    
    269
    -bignat_shiftr_neg mwa wa n
    
    270
    -   = mwaCompareOp mwa
    
    271
    -      (\m -> Other.bignat_shiftr_neg m wa n)
    
    272
    -      (\m -> Native.bignat_shiftr_neg m wa n)
    
    273
    -
    
    274
    -bignat_or
    
    275
    -   :: MutableWordArray# RealWorld
    
    276
    -   -> WordArray#
    
    277
    -   -> WordArray#
    
    278
    -   -> State# RealWorld
    
    279
    -   -> State# RealWorld
    
    280
    -bignat_or mwa wa wb
    
    281
    -   = mwaCompareOp mwa
    
    282
    -      (\m -> Other.bignat_or m wa wb)
    
    283
    -      (\m -> Native.bignat_or m wa wb)
    
    284
    -
    
    285
    -bignat_xor
    
    286
    -   :: MutableWordArray# RealWorld
    
    287
    -   -> WordArray#
    
    288
    -   -> WordArray#
    
    289
    -   -> State# RealWorld
    
    290
    -   -> State# RealWorld
    
    291
    -bignat_xor mwa wa wb
    
    292
    -   = mwaCompareOp mwa
    
    293
    -      (\m -> Other.bignat_xor m wa wb)
    
    294
    -      (\m -> Native.bignat_xor m wa wb)
    
    295
    -
    
    296
    -bignat_and
    
    297
    -   :: MutableWordArray# RealWorld
    
    298
    -   -> WordArray#
    
    299
    -   -> WordArray#
    
    300
    -   -> State# RealWorld
    
    301
    -   -> State# RealWorld
    
    302
    -bignat_and mwa wa wb
    
    303
    -   = mwaCompareOp mwa
    
    304
    -      (\m -> Other.bignat_and m wa wb)
    
    305
    -      (\m -> Native.bignat_and m wa wb)
    
    306
    -
    
    307
    -bignat_and_not
    
    308
    -   :: MutableWordArray# RealWorld
    
    309
    -   -> WordArray#
    
    310
    -   -> WordArray#
    
    311
    -   -> State# RealWorld
    
    312
    -   -> State# RealWorld
    
    313
    -bignat_and_not mwa wa wb
    
    314
    -   = mwaCompareOp mwa
    
    315
    -      (\m -> Other.bignat_and_not m wa wb)
    
    316
    -      (\m -> Native.bignat_and_not m wa wb)
    
    317
    -
    
    318
    -bignat_quotrem
    
    319
    -   :: MutableWordArray# RealWorld
    
    320
    -   -> MutableWordArray# RealWorld
    
    321
    -   -> WordArray#
    
    322
    -   -> WordArray#
    
    323
    -   -> State# RealWorld
    
    324
    -   -> State# RealWorld
    
    325
    -bignat_quotrem mwq mwr wa wb
    
    326
    -   = mwaCompareOp2 mwq mwr
    
    327
    -      (\m1 m2 -> Other.bignat_quotrem m1 m2 wa wb)
    
    328
    -      (\m1 m2 -> Native.bignat_quotrem m1 m2 wa wb)
    
    329
    -
    
    330
    -bignat_quot
    
    331
    -   :: MutableWordArray# RealWorld
    
    332
    -   -> WordArray#
    
    333
    -   -> WordArray#
    
    334
    -   -> State# RealWorld
    
    335
    -   -> State# RealWorld
    
    336
    -bignat_quot mwq wa wb
    
    337
    -   = mwaCompareOp mwq
    
    338
    -      (\m -> Other.bignat_quot m wa wb)
    
    339
    -      (\m -> Native.bignat_quot m wa wb)
    
    340
    -
    
    341
    -bignat_rem
    
    342
    -   :: MutableWordArray# RealWorld
    
    343
    -   -> WordArray#
    
    344
    -   -> WordArray#
    
    345
    -   -> State# RealWorld
    
    346
    -   -> State# RealWorld
    
    347
    -bignat_rem mwr wa wb
    
    348
    -   = mwaCompareOp mwr
    
    349
    -      (\m -> Other.bignat_rem m wa wb)
    
    350
    -      (\m -> Native.bignat_rem m wa wb)
    
    351
    -
    
    352
    -bignat_quotrem_word
    
    353
    -   :: MutableWordArray# RealWorld
    
    354
    -   -> WordArray#
    
    355
    -   -> Word#
    
    356
    -   -> State# RealWorld
    
    357
    -   -> (# State# RealWorld, Word# #)
    
    358
    -bignat_quotrem_word mwq wa b
    
    359
    -   = mwaCompareOpWord mwq
    
    360
    -      (\m -> Other.bignat_quotrem_word m wa b)
    
    361
    -      (\m -> Native.bignat_quotrem_word m wa b)
    
    362
    -
    
    363
    -bignat_quot_word
    
    364
    -   :: MutableWordArray# RealWorld
    
    365
    -   -> WordArray#
    
    366
    -   -> Word#
    
    367
    -   -> State# RealWorld
    
    368
    -   -> State# RealWorld
    
    369
    -bignat_quot_word mwq wa b
    
    370
    -   = mwaCompareOp mwq
    
    371
    -      (\m -> Other.bignat_quot_word m wa b)
    
    372
    -      (\m -> Native.bignat_quot_word m wa b)
    
    373
    -
    
    374
    -bignat_rem_word
    
    375
    -   :: WordArray#
    
    376
    -   -> Word#
    
    377
    -   -> Word#
    
    378
    -bignat_rem_word wa b =
    
    379
    -   let
    
    380
    -      gr = Other.bignat_rem_word wa b
    
    381
    -      nr = Native.bignat_rem_word wa b
    
    382
    -   in case gr `eqWord#` nr of
    
    383
    -       1# -> gr
    
    384
    -       _  -> unexpectedValue_Word# (# #)
    
    385
    -
    
    386
    -bignat_gcd
    
    387
    -   :: MutableWordArray# RealWorld
    
    388
    -   -> WordArray#
    
    389
    -   -> WordArray#
    
    390
    -   -> State# RealWorld
    
    391
    -   -> State# RealWorld
    
    392
    -bignat_gcd mwr wa wb
    
    393
    -   = mwaCompareOp mwr
    
    394
    -      (\m -> Other.bignat_gcd m wa wb)
    
    395
    -      (\m -> Native.bignat_gcd m wa wb)
    
    396
    -
    
    397
    -bignat_gcd_word
    
    398
    -   :: WordArray#
    
    399
    -   -> Word#
    
    400
    -   -> Word#
    
    401
    -bignat_gcd_word wa b =
    
    402
    -   let
    
    403
    -      gr = Other.bignat_gcd_word wa b
    
    404
    -      nr = Native.bignat_gcd_word wa b
    
    405
    -   in case gr `eqWord#` nr of
    
    406
    -       1# -> gr
    
    407
    -       _  -> unexpectedValue_Word# (# #)
    
    408
    -
    
    409
    -bignat_gcd_word_word
    
    410
    -   :: Word#
    
    411
    -   -> Word#
    
    412
    -   -> Word#
    
    413
    -bignat_gcd_word_word a b =
    
    414
    -   let
    
    415
    -      gr = Other.bignat_gcd_word_word a b
    
    416
    -      nr = Native.bignat_gcd_word_word a b
    
    417
    -   in case gr `eqWord#` nr of
    
    418
    -       1# -> gr
    
    419
    -       _  -> unexpectedValue_Word# (# #)
    
    420
    -
    
    421
    -bignat_encode_double :: WordArray# -> Int# -> Double#
    
    422
    -bignat_encode_double a e =
    
    423
    -   let
    
    424
    -      gr = Other.bignat_encode_double a e
    
    425
    -      nr = Native.bignat_encode_double a e
    
    426
    -   in case gr ==## nr of
    
    427
    -       1# -> gr
    
    428
    -       _  -> case unexpectedValue of
    
    429
    -               !_ -> 0.0##
    
    430
    -               -- see Note [ghc-bignum exceptions] in GHC.Num.Primitives
    
    431
    -
    
    432
    -bignat_powmod_word :: WordArray# -> WordArray# -> Word# -> Word#
    
    433
    -bignat_powmod_word b e m =
    
    434
    -   let
    
    435
    -      gr = Other.bignat_powmod_word b e m
    
    436
    -      nr = Native.bignat_powmod_word b e m
    
    437
    -   in case gr `eqWord#` nr of
    
    438
    -       1# -> gr
    
    439
    -       _  -> unexpectedValue_Word# (# #)
    
    440
    -
    
    441
    -bignat_powmod
    
    442
    -   :: MutableWordArray# RealWorld
    
    443
    -   -> WordArray#
    
    444
    -   -> WordArray#
    
    445
    -   -> WordArray#
    
    446
    -   -> State# RealWorld
    
    447
    -   -> State# RealWorld
    
    448
    -bignat_powmod r b e m
    
    449
    -   = mwaCompareOp r
    
    450
    -      (\r' -> Other.bignat_powmod r' b e m)
    
    451
    -      (\r' -> Native.bignat_powmod r' b e m)
    
    452
    -
    
    453
    -bignat_powmod_words
    
    454
    -   :: Word#
    
    455
    -   -> Word#
    
    456
    -   -> Word#
    
    457
    -   -> Word#
    
    458
    -bignat_powmod_words b e m =
    
    459
    -   let
    
    460
    -      gr = Other.bignat_powmod_words b e m
    
    461
    -      nr = Native.bignat_powmod_words b e m
    
    462
    -   in case gr `eqWord#` nr of
    
    463
    -       1# -> gr
    
    464
    -       _  -> unexpectedValue_Word# (# #)
    
    465
    -
    
    466
    -integer_gcde
    
    467
    -   :: Integer
    
    468
    -   -> Integer
    
    469
    -   -> (# Integer, Integer, Integer #)
    
    470
    -integer_gcde a b =
    
    471
    -   let
    
    472
    -      !(# g0,x0,y0 #) = Other.integer_gcde a b
    
    473
    -      !(# g1,x1,y1 #) = Native.integer_gcde a b
    
    474
    -   in if isTrue# (integerEq# x0 x1
    
    475
    -                  &&# integerEq# y0 y1
    
    476
    -                  &&# integerEq# g0 g1)
    
    477
    -         then (# g0, x0, y0 #)
    
    478
    -         else case unexpectedValue of
    
    479
    -            !_ -> (# integerZero, integerZero, integerZero #)
    
    480
    -
    
    481
    -integer_recip_mod
    
    482
    -   :: Integer
    
    483
    -   -> Natural
    
    484
    -   -> (# Natural | () #)
    
    485
    -integer_recip_mod x m =
    
    486
    -   let
    
    487
    -      !r0 = Other.integer_recip_mod x m
    
    488
    -      !r1 = Native.integer_recip_mod x m
    
    489
    -   in case (# r0, r1 #) of
    
    490
    -         (# (# | () #), (# | () #) #) -> r0
    
    491
    -         (# (# y0 | #), (# y1 | #) #)
    
    492
    -            | isTrue# (naturalEq# y0 y1) -> r0
    
    493
    -         _ -> case unexpectedValue of
    
    494
    -            !_ -> (# | () #)
    
    495
    -
    
    496
    -integer_powmod
    
    497
    -   :: Integer
    
    498
    -   -> Natural
    
    499
    -   -> Natural
    
    500
    -   -> Natural
    
    501
    -integer_powmod b e m =
    
    502
    -   let
    
    503
    -      !r0 = Other.integer_powmod b e m
    
    504
    -      !r1 = Native.integer_powmod b e m
    
    505
    -   in if isTrue# (naturalEq# r0 r1)
    
    506
    -         then r0
    
    507
    -         else case unexpectedValue of
    
    508
    -               !_ -> naturalZero

  • libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/FFI.hs deleted
    1
    -{-# LANGUAGE NoImplicitPrelude #-}
    
    2
    -{-# LANGUAGE BangPatterns #-}
    
    3
    -{-# LANGUAGE GHCForeignImportPrim #-}
    
    4
    -{-# LANGUAGE MagicHash #-}
    
    5
    -{-# LANGUAGE UnboxedTuples #-}
    
    6
    -{-# LANGUAGE UnliftedFFITypes #-}
    
    7
    -{-# LANGUAGE NegativeLiterals #-}
    
    8
    -{-# LANGUAGE ForeignFunctionInterface #-}
    
    9
    -
    
    10
    --- | External BigNat backend that directly call FFI operations.
    
    11
    ---
    
    12
    --- This backend can be useful for specific compilers such as GHCJS or Asterius
    
    13
    --- that replace bignat foreign calls with calls to the native platform bignat
    
    14
    --- library (e.g. JavaScript's BigInt). You can also link an extra object
    
    15
    --- providing the implementation.
    
    16
    -module GHC.Internal.Bignum.Backend.FFI where
    
    17
    -
    
    18
    -import GHC.Internal.Prim
    
    19
    -import GHC.Internal.Types
    
    20
    -import GHC.Internal.Bignum.WordArray
    
    21
    -import GHC.Internal.Bignum.Primitives
    
    22
    -import qualified GHC.Internal.Bignum.Backend.Native as Native
    
    23
    -import {-# SOURCE #-} GHC.Internal.Bignum.Natural
    
    24
    -import {-# SOURCE #-} GHC.Internal.Bignum.Integer
    
    25
    -
    
    26
    --- See W1 of Note [Tracking dependencies on primitives] in GHC.Internal.Base
    
    27
    --- (This module uses the empty tuple () and string literals.)
    
    28
    -import GHC.Internal.Tuple ()
    
    29
    -import GHC.Internal.CString ()
    
    30
    -
    
    31
    -default ()
    
    32
    -
    
    33
    --- | ghc-bignum backend name
    
    34
    -backendName :: [Char]
    
    35
    -backendName = "ffi"
    
    36
    -
    
    37
    --- | Compare two non-zero BigNat of the same length
    
    38
    ---
    
    39
    --- Return:
    
    40
    ---     < 0 ==> LT
    
    41
    ---    == 0 ==> EQ
    
    42
    ---     > 0 ==> GT
    
    43
    -bignat_compare
    
    44
    -   :: WordArray#
    
    45
    -   -> WordArray#
    
    46
    -   -> Int#
    
    47
    -bignat_compare = ghc_bignat_compare
    
    48
    -
    
    49
    -foreign import ccall unsafe ghc_bignat_compare
    
    50
    -   :: WordArray#
    
    51
    -   -> WordArray#
    
    52
    -   -> Int#
    
    53
    -
    
    54
    --- | Add two non-zero BigNat
    
    55
    ---
    
    56
    --- Result is to be stored in the MutableWordArray#.
    
    57
    --- The latter has size: max (size a, size b) + 1
    
    58
    ---
    
    59
    --- The potential 0 most-significant Word (i.e. the potential carry) will be
    
    60
    --- removed by the caller if it is not already done by the backend.
    
    61
    -bignat_add
    
    62
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    63
    -   -> WordArray#
    
    64
    -   -> WordArray#
    
    65
    -   -> State# RealWorld
    
    66
    -   -> State# RealWorld
    
    67
    -bignat_add mwa wa wb s
    
    68
    -   = ioVoid (ghc_bignat_add mwa wa wb) s
    
    69
    -
    
    70
    -foreign import ccall unsafe ghc_bignat_add
    
    71
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    72
    -   -> WordArray#
    
    73
    -   -> WordArray#
    
    74
    -   -> IO ()
    
    75
    -
    
    76
    --- | Add a non-zero BigNat and a non-zero Word#
    
    77
    ---
    
    78
    --- Result is to be stored in the MutableWordArray#.
    
    79
    --- The latter has size: size a + 1
    
    80
    ---
    
    81
    --- The potential 0 most-significant Word (i.e. the potential carry) will be
    
    82
    --- removed by the caller if it is not already done by the backend.
    
    83
    -bignat_add_word
    
    84
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    85
    -   -> WordArray#
    
    86
    -   -> Word#
    
    87
    -   -> State# RealWorld
    
    88
    -   -> State# RealWorld
    
    89
    -bignat_add_word mwa wa b s =
    
    90
    -   ioVoid (ghc_bignat_add_word mwa wa b) s
    
    91
    -
    
    92
    -foreign import ccall unsafe ghc_bignat_add_word
    
    93
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    94
    -   -> WordArray#
    
    95
    -   -> Word#
    
    96
    -   -> IO ()
    
    97
    -
    
    98
    --- | Multiply a non-zero BigNat and a non-zero Word#
    
    99
    ---
    
    100
    --- Result is to be stored in the MutableWordArray#.
    
    101
    --- The latter has size: size a + 1
    
    102
    ---
    
    103
    --- The potential 0 most-significant Word (i.e. the potential carry) will be
    
    104
    --- removed by the caller if it is not already done by the backend.
    
    105
    -bignat_mul_word
    
    106
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    107
    -   -> WordArray#
    
    108
    -   -> Word#
    
    109
    -   -> State# RealWorld
    
    110
    -   -> State# RealWorld
    
    111
    -bignat_mul_word mwa wa b s =
    
    112
    -   ioVoid (ghc_bignat_mul_word mwa wa b) s
    
    113
    -
    
    114
    -foreign import ccall unsafe ghc_bignat_mul_word
    
    115
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    116
    -   -> WordArray#
    
    117
    -   -> Word#
    
    118
    -   -> IO ()
    
    119
    -
    
    120
    --- | Sub two non-zero BigNat
    
    121
    ---
    
    122
    --- Result is to be stored in the MutableWordArray#.
    
    123
    --- The latter has size: size a
    
    124
    ---
    
    125
    --- The potential 0 most-significant Words will be removed by the caller if it is
    
    126
    --- not already done by the backend.
    
    127
    ---
    
    128
    --- Return False# to indicate underflow.
    
    129
    -bignat_sub
    
    130
    -   :: MutableWordArray# RealWorld
    
    131
    -   -> WordArray#
    
    132
    -   -> WordArray#
    
    133
    -   -> State# RealWorld
    
    134
    -   -> (# State# RealWorld, Bool# #)
    
    135
    -bignat_sub mwa wa wb s = ioBool (ghc_bignat_sub mwa wa wb) s
    
    136
    -
    
    137
    -foreign import ccall unsafe ghc_bignat_sub
    
    138
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    139
    -   -> WordArray#
    
    140
    -   -> WordArray#
    
    141
    -   -> IO Bool
    
    142
    -
    
    143
    --- | Sub a non-zero word from a non-zero BigNat
    
    144
    ---
    
    145
    --- Result is to be stored in the MutableWordArray#.
    
    146
    --- The latter has size: size a
    
    147
    ---
    
    148
    --- The potential 0 most-significant Words will be removed by the caller if it is
    
    149
    --- not already done by the backend.
    
    150
    ---
    
    151
    --- Return False# to indicate underflow.
    
    152
    -bignat_sub_word
    
    153
    -   :: MutableWordArray# RealWorld
    
    154
    -   -> WordArray#
    
    155
    -   -> Word#
    
    156
    -   -> State# RealWorld
    
    157
    -   -> (# State# RealWorld, Bool# #)
    
    158
    -bignat_sub_word mwa wa b s = ioBool (ghc_bignat_sub_word mwa wa b) s
    
    159
    -
    
    160
    -foreign import ccall unsafe ghc_bignat_sub_word
    
    161
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    162
    -   -> WordArray#
    
    163
    -   -> Word#
    
    164
    -   -> IO Bool
    
    165
    -
    
    166
    --- | Multiply two non-zero BigNat
    
    167
    ---
    
    168
    --- Result is to be stored in the MutableWordArray#.
    
    169
    --- The latter has size: size a+size b
    
    170
    ---
    
    171
    --- The potential 0 most-significant Word (i.e. the potential carry) will be
    
    172
    --- removed by the caller if it is not already done by the backend.
    
    173
    -bignat_mul
    
    174
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    175
    -   -> WordArray#
    
    176
    -   -> WordArray#
    
    177
    -   -> State# RealWorld
    
    178
    -   -> State# RealWorld
    
    179
    -bignat_mul mwa wa wb s = ioVoid (ghc_bignat_mul mwa wa wb) s
    
    180
    -
    
    181
    -foreign import ccall unsafe ghc_bignat_mul
    
    182
    -   :: MutableWordArray# RealWorld -- ^ Result
    
    183
    -   -> WordArray#
    
    184
    -   -> WordArray#
    
    185
    -   -> IO ()
    
    186
    -
    
    187
    --- | PopCount of a non-zero BigNat
    
    188
    -bignat_popcount :: WordArray# -> Word#
    
    189
    -bignat_popcount = ghc_bignat_popcount
    
    190
    -
    
    191
    -foreign import ccall unsafe ghc_bignat_popcount
    
    192
    -   :: WordArray#
    
    193
    -   -> Word#
    
    194
    -
    
    195
    --- | Left-shift a non-zero BigNat by a non-zero amount of bits
    
    196
    ---
    
    197
    --- Result is to be stored in the MutableWordArray#.
    
    198
    --- The latter has size: size a + required new limbs
    
    199
    ---
    
    200
    --- The potential 0 most-significant Word (i.e. the potential carry) will be
    
    201
    --- removed by the caller if it is not already done by the backend.
    
    202
    -bignat_shiftl
    
    203
    -   :: MutableWordArray# RealWorld
    
    204
    -   -> WordArray#
    
    205
    -   -> Word#
    
    206
    -   -> State# RealWorld
    
    207
    -   -> State# RealWorld
    
    208
    -bignat_shiftl mwa wa n s = ioVoid (ghc_bignat_shiftl mwa wa n) s
    
    209
    -
    
    210
    -foreign import ccall unsafe ghc_bignat_shiftl
    
    211
    -   :: MutableWordArray# RealWorld
    
    212
    -   -> WordArray#
    
    213
    -   -> Word#
    
    214
    -   -> IO ()
    
    215
    -
    
    216
    --- | Right-shift a non-zero BigNat by a non-zero amount of bits
    
    217
    ---
    
    218
    --- Result is to be stored in the MutableWordArray#.
    
    219
    --- The latter has size: required limbs
    
    220
    ---
    
    221
    --- The potential 0 most-significant Word (i.e. the potential carry) will be
    
    222
    --- removed by the caller if it is not already done by the backend.
    
    223
    -bignat_shiftr
    
    224
    -   :: MutableWordArray# RealWorld
    
    225
    -   -> WordArray#
    
    226
    -   -> Word#
    
    227
    -   -> State# RealWorld
    
    228
    -   -> State# RealWorld
    
    229
    -bignat_shiftr mwa wa n s = ioVoid (ghc_bignat_shiftr mwa wa n) s
    
    230
    -
    
    231
    -foreign import ccall unsafe ghc_bignat_shiftr
    
    232
    -   :: MutableWordArray# RealWorld
    
    233
    -   -> WordArray#
    
    234
    -   -> Word#
    
    235
    -   -> IO ()
    
    236
    -
    
    237
    --- | Right-shift a non-zero BigNat by a non-zero amount of bits by first
    
    238
    --- converting it into its two's complement representation and then again after
    
    239
    --- the arithmetic shift.
    
    240
    ---
    
    241
    --- Result is to be stored in the MutableWordArray#.
    
    242
    --- The latter has size: required limbs
    
    243
    ---
    
    244
    --- The potential 0 most-significant Words (i.e. the potential carry) will be
    
    245
    --- removed by the caller if it is not already done by the backend.
    
    246
    -bignat_shiftr_neg
    
    247
    -   :: MutableWordArray# RealWorld
    
    248
    -   -> WordArray#
    
    249
    -   -> Word#
    
    250
    -   -> State# RealWorld
    
    251
    -   -> State# RealWorld
    
    252
    -bignat_shiftr_neg mwa wa n s = ioVoid (ghc_bignat_shiftr_neg mwa wa n) s
    
    253
    -
    
    254
    -foreign import ccall unsafe ghc_bignat_shiftr_neg
    
    255
    -   :: MutableWordArray# RealWorld
    
    256
    -   -> WordArray#
    
    257
    -   -> Word#
    
    258
    -   -> IO ()
    
    259
    -
    
    260
    -
    
    261
    --- | OR two non-zero BigNat
    
    262
    ---
    
    263
    --- Result is to be stored in the MutableWordArray#.
    
    264
    --- The latter has size: max (size a, size b)
    
    265
    -bignat_or
    
    266
    -   :: MutableWordArray# RealWorld
    
    267
    -   -> WordArray#
    
    268
    -   -> WordArray#
    
    269
    -   -> State# RealWorld
    
    270
    -   -> State# RealWorld
    
    271
    -{-# INLINE bignat_or #-}
    
    272
    -bignat_or mwa wa wb s = ioVoid (ghc_bignat_or mwa wa wb) s
    
    273
    -
    
    274
    -foreign import ccall unsafe ghc_bignat_or
    
    275
    -   :: MutableWordArray# RealWorld
    
    276
    -   -> WordArray#
    
    277
    -   -> WordArray#
    
    278
    -   -> IO ()
    
    279
    -
    
    280
    --- | XOR two non-zero BigNat
    
    281
    ---
    
    282
    --- Result is to be stored in the MutableWordArray#.
    
    283
    --- The latter has size: max (size a, size b)
    
    284
    ---
    
    285
    --- The potential 0 most-significant Words will be removed by the caller if it is
    
    286
    --- not already done by the backend.
    
    287
    -bignat_xor
    
    288
    -   :: MutableWordArray# RealWorld
    
    289
    -   -> WordArray#
    
    290
    -   -> WordArray#
    
    291
    -   -> State# RealWorld
    
    292
    -   -> State# RealWorld
    
    293
    -{-# INLINE bignat_xor #-}
    
    294
    -bignat_xor mwa wa wb s = ioVoid (ghc_bignat_xor mwa wa wb) s
    
    295
    -
    
    296
    -foreign import ccall unsafe ghc_bignat_xor
    
    297
    -   :: MutableWordArray# RealWorld
    
    298
    -   -> WordArray#
    
    299
    -   -> WordArray#
    
    300
    -   -> IO ()
    
    301
    -
    
    302
    --- | AND two non-zero BigNat
    
    303
    ---
    
    304
    --- Result is to be stored in the MutableWordArray#.
    
    305
    --- The latter has size: min (size a, size b)
    
    306
    ---
    
    307
    --- The potential 0 most-significant Words will be removed by the caller if it is
    
    308
    --- not already done by the backend.
    
    309
    -bignat_and
    
    310
    -   :: MutableWordArray# RealWorld
    
    311
    -   -> WordArray#
    
    312
    -   -> WordArray#
    
    313
    -   -> State# RealWorld
    
    314
    -   -> State# RealWorld
    
    315
    -{-# INLINE bignat_and #-}
    
    316
    -bignat_and mwa wa wb s = ioVoid (ghc_bignat_and mwa wa wb) s
    
    317
    -
    
    318
    -foreign import ccall unsafe ghc_bignat_and
    
    319
    -   :: MutableWordArray# RealWorld
    
    320
    -   -> WordArray#
    
    321
    -   -> WordArray#
    
    322
    -   -> IO ()
    
    323
    -
    
    324
    --- | ANDNOT two non-zero BigNat
    
    325
    ---
    
    326
    --- Result is to be stored in the MutableWordArray#.
    
    327
    --- The latter has size: size a
    
    328
    ---
    
    329
    --- The potential 0 most-significant Words will be removed by the caller if it is
    
    330
    --- not already done by the backend.
    
    331
    -bignat_and_not
    
    332
    -   :: MutableWordArray# RealWorld
    
    333
    -   -> WordArray#
    
    334
    -   -> WordArray#
    
    335
    -   -> State# RealWorld
    
    336
    -   -> State# RealWorld
    
    337
    -{-# INLINE bignat_and_not #-}
    
    338
    -bignat_and_not mwa wa wb s = ioVoid (ghc_bignat_and_not mwa wa wb) s
    
    339
    -
    
    340
    -foreign import ccall unsafe ghc_bignat_and_not
    
    341
    -   :: MutableWordArray# RealWorld
    
    342
    -   -> WordArray#
    
    343
    -   -> WordArray#
    
    344
    -   -> IO ()
    
    345
    -
    
    346
    --- | QuotRem of two non-zero BigNat
    
    347
    ---
    
    348
    --- Result quotient and remainder are to be stored in the MutableWordArray#.
    
    349
    --- The first one (quotient) has size: size(A)-size(B)+1
    
    350
    --- The second one (remainder) has size: size(b)
    
    351
    ---
    
    352
    --- The potential 0 most-significant Words will be removed by the caller if it is
    
    353
    --- not already done by the backend.
    
    354
    -bignat_quotrem
    
    355
    -   :: MutableWordArray# RealWorld -- ^ Quotient
    
    356
    -   -> MutableWordArray# RealWorld -- ^ Remainder
    
    357
    -   -> WordArray#
    
    358
    -   -> WordArray#
    
    359
    -   -> State# RealWorld
    
    360
    -   -> State# RealWorld
    
    361
    -bignat_quotrem mwq mwr wa wb s =
    
    362
    -   ioVoid (ghc_bignat_quotrem mwq mwr wa wb) s
    
    363
    -
    
    364
    -foreign import ccall unsafe ghc_bignat_quotrem
    
    365
    -   :: MutableWordArray# RealWorld
    
    366
    -   -> MutableWordArray# RealWorld
    
    367
    -   -> WordArray#
    
    368
    -   -> WordArray#
    
    369
    -   -> IO ()
    
    370
    -
    
    371
    --- | Quotient of two non-zero BigNat
    
    372
    ---
    
    373
    --- Result quotient is to be stored in the MutableWordArray#.
    
    374
    --- The latter has size: size(A)-size(B)+1
    
    375
    ---
    
    376
    --- The potential 0 most-significant Words will be removed by the caller if it is
    
    377
    --- not already done by the backend.
    
    378
    -bignat_quot
    
    379
    -   :: MutableWordArray# RealWorld -- ^ Quotient
    
    380
    -   -> WordArray#
    
    381
    -   -> WordArray#
    
    382
    -   -> State# RealWorld
    
    383
    -   -> State# RealWorld
    
    384
    -bignat_quot mwq wa wb s =
    
    385
    -   ioVoid (ghc_bignat_quot mwq wa wb) s
    
    386
    -
    
    387
    -foreign import ccall unsafe ghc_bignat_quot
    
    388
    -   :: MutableWordArray# RealWorld
    
    389
    -   -> WordArray#
    
    390
    -   -> WordArray#
    
    391
    -   -> IO ()
    
    392
    -
    
    393
    --- | Remainder of two non-zero BigNat
    
    394
    ---
    
    395
    --- Result remainder is to be stored in the MutableWordArray#.
    
    396
    --- The latter has size: size(B)
    
    397
    ---
    
    398
    --- The potential 0 most-significant Words will be removed by the caller if it is
    
    399
    --- not already done by the backend.
    
    400
    -bignat_rem
    
    401
    -   :: MutableWordArray# RealWorld -- ^ Quotient
    
    402
    -   -> WordArray#
    
    403
    -   -> WordArray#
    
    404
    -   -> State# RealWorld
    
    405
    -   -> State# RealWorld
    
    406
    -bignat_rem mwr wa wb s =
    
    407
    -   ioVoid (ghc_bignat_rem mwr wa wb) s
    
    408
    -
    
    409
    -foreign import ccall unsafe ghc_bignat_rem
    
    410
    -   :: MutableWordArray# RealWorld
    
    411
    -   -> WordArray#
    
    412
    -   -> WordArray#
    
    413
    -   -> IO ()
    
    414
    -
    
    415
    --- | QuotRem of a non-zero BigNat and a non-zero Word
    
    416
    ---
    
    417
    --- Result quotient is to be stored in the MutableWordArray#.
    
    418
    --- The latter has size: size(A)
    
    419
    ---
    
    420
    --- The remainder is returned.
    
    421
    ---
    
    422
    --- The potential 0 most-significant Words will be removed by the caller if it is
    
    423
    --- not already done by the backend.
    
    424
    -bignat_quotrem_word
    
    425
    -   :: MutableWordArray# RealWorld -- ^ Quotient
    
    426
    -   -> WordArray#
    
    427
    -   -> Word#
    
    428
    -   -> State# RealWorld
    
    429
    -   -> (# State# RealWorld, Word# #)
    
    430
    -bignat_quotrem_word mwq wa b s =
    
    431
    -   ioWord# (ghc_bignat_quotrem_word mwq wa b) s
    
    432
    -
    
    433
    -foreign import ccall unsafe ghc_bignat_quotrem_word
    
    434
    -   :: MutableWordArray# RealWorld
    
    435
    -   -> WordArray#
    
    436
    -   -> Word#
    
    437
    -   -> IO Word
    
    438
    -
    
    439
    --- | Quot of a non-zero BigNat and a non-zero Word
    
    440
    ---
    
    441
    --- Result quotient is to be stored in the MutableWordArray#.
    
    442
    --- The latter has size: size(A)
    
    443
    ---
    
    444
    --- The potential 0 most-significant Words will be removed by the caller if it is
    
    445
    --- not already done by the backend.
    
    446
    -bignat_quot_word
    
    447
    -   :: MutableWordArray# RealWorld -- ^ Quotient
    
    448
    -   -> WordArray#
    
    449
    -   -> Word#
    
    450
    -   -> State# RealWorld
    
    451
    -   -> State# RealWorld
    
    452
    -bignat_quot_word mwq wa b s =
    
    453
    -   ioVoid (ghc_bignat_quot_word mwq wa b) s
    
    454
    -
    
    455
    -foreign import ccall unsafe ghc_bignat_quot_word
    
    456
    -   :: MutableWordArray# RealWorld
    
    457
    -   -> WordArray#
    
    458
    -   -> Word#
    
    459
    -   -> IO ()
    
    460
    -
    
    461
    --- | Remainder of a non-zero BigNat and a non-zero Word
    
    462
    ---
    
    463
    --- The remainder is returned.
    
    464
    -bignat_rem_word
    
    465
    -   :: WordArray#
    
    466
    -   -> Word#
    
    467
    -   -> Word#
    
    468
    -bignat_rem_word = ghc_bignat_rem_word
    
    469
    -
    
    470
    -foreign import ccall unsafe ghc_bignat_rem_word
    
    471
    -   :: WordArray#
    
    472
    -   -> Word#
    
    473
    -   -> Word#
    
    474
    -
    
    475
    -
    
    476
    --- | Greatest common divisor (GCD) of two non-zero and non-one BigNat
    
    477
    ---
    
    478
    --- Result GCD is to be stored in the MutableWordArray#.
    
    479
    --- The latter has size: size(B)
    
    480
    --- The first WordArray# is greater than the second WordArray#.
    
    481
    ---
    
    482
    --- The potential 0 most-significant Words will be removed by the caller if it is
    
    483
    --- not already done by the backend.
    
    484
    -bignat_gcd
    
    485
    -   :: MutableWordArray# RealWorld
    
    486
    -   -> WordArray#
    
    487
    -   -> WordArray#
    
    488
    -   -> State# RealWorld
    
    489
    -   -> State# RealWorld
    
    490
    -bignat_gcd mwr wa wb s =
    
    491
    -   ioVoid (ghc_bignat_gcd mwr wa wb) s
    
    492
    -
    
    493
    -foreign import ccall unsafe ghc_bignat_gcd
    
    494
    -   :: MutableWordArray# RealWorld
    
    495
    -   -> WordArray#
    
    496
    -   -> WordArray#
    
    497
    -   -> IO ()
    
    498
    -
    
    499
    --- | Greatest common divisor (GCD) of a non-zero/non-one BigNat and a
    
    500
    --- non-zero/non-one Word#
    
    501
    ---
    
    502
    --- Result GCD is returned
    
    503
    -bignat_gcd_word
    
    504
    -   :: WordArray#
    
    505
    -   -> Word#
    
    506
    -   -> Word#
    
    507
    -bignat_gcd_word = ghc_bignat_gcd_word
    
    508
    -
    
    509
    -foreign import ccall unsafe ghc_bignat_gcd_word
    
    510
    -   :: WordArray#
    
    511
    -   -> Word#
    
    512
    -   -> Word#
    
    513
    -
    
    514
    --- | Greatest common divisor (GCD) of two Word#
    
    515
    ---
    
    516
    --- Result GCD is returned
    
    517
    -bignat_gcd_word_word
    
    518
    -   :: Word#
    
    519
    -   -> Word#
    
    520
    -   -> Word#
    
    521
    -bignat_gcd_word_word = ghc_bignat_gcd_word_word
    
    522
    -
    
    523
    -foreign import ccall unsafe ghc_bignat_gcd_word_word
    
    524
    -   :: Word#
    
    525
    -   -> Word#
    
    526
    -   -> Word#
    
    527
    -
    
    528
    --- | Encode (# BigNat mantissa, Int# exponent #) into a Double#
    
    529
    -bignat_encode_double :: WordArray# -> Int# -> Double#
    
    530
    -bignat_encode_double = ghc_bignat_encode_double
    
    531
    -
    
    532
    -foreign import ccall unsafe ghc_bignat_encode_double
    
    533
    -   :: WordArray#
    
    534
    -   -> Int#
    
    535
    -   -> Double#
    
    536
    -
    
    537
    --- | \"@'bignat_powmod_word' /b/ /e/ /m/@\" computes base @/b/@ raised to
    
    538
    --- exponent @/e/@ modulo @/m/@.
    
    539
    ---
    
    540
    --- b > 1
    
    541
    --- e > 0
    
    542
    --- m > 1
    
    543
    -bignat_powmod_word :: WordArray# -> WordArray# -> Word# -> Word#
    
    544
    -bignat_powmod_word = ghc_bignat_powmod_word
    
    545
    -
    
    546
    -foreign import ccall unsafe ghc_bignat_powmod_word
    
    547
    -   :: WordArray# -> WordArray# -> Word# -> Word#
    
    548
    -
    
    549
    --- | \"@'bignat_powmod' r /b/ /e/ /m/@\" computes base @/b/@ raised to
    
    550
    --- exponent @/e/@ modulo @/m/@.
    
    551
    ---
    
    552
    --- b > 1
    
    553
    --- e > 0
    
    554
    --- m > 1
    
    555
    ---
    
    556
    --- Result is to be stored in the MutableWordArray# (which size is equal to the
    
    557
    --- one of m).
    
    558
    ---
    
    559
    --- The potential 0 most-significant Words will be removed by the caller if it is
    
    560
    --- not already done by the backend.
    
    561
    -bignat_powmod
    
    562
    -   :: MutableWordArray# RealWorld
    
    563
    -   -> WordArray#
    
    564
    -   -> WordArray#
    
    565
    -   -> WordArray#
    
    566
    -   -> State# RealWorld
    
    567
    -   -> State# RealWorld
    
    568
    -bignat_powmod r b e m s =
    
    569
    -   ioVoid (ghc_bignat_powmod r b e m) s
    
    570
    -
    
    571
    -foreign import ccall unsafe ghc_bignat_powmod
    
    572
    -   :: MutableWordArray# RealWorld
    
    573
    -   -> WordArray#
    
    574
    -   -> WordArray#
    
    575
    -   -> WordArray#
    
    576
    -   -> IO ()
    
    577
    -
    
    578
    --- | \"@'bignat_powmod' /b/ /e/ /m/@\" computes base @/b/@ raised to
    
    579
    --- exponent @/e/@ modulo @/m/@.
    
    580
    ---
    
    581
    --- b > 1
    
    582
    --- e > 0
    
    583
    --- m > 1
    
    584
    -bignat_powmod_words
    
    585
    -   :: Word#
    
    586
    -   -> Word#
    
    587
    -   -> Word#
    
    588
    -   -> Word#
    
    589
    -bignat_powmod_words = ghc_bignat_powmod_words
    
    590
    -
    
    591
    -foreign import ccall unsafe ghc_bignat_powmod_words
    
    592
    -   :: Word# -> Word# -> Word# -> Word#
    
    593
    -
    
    594
    -
    
    595
    --- | Return extended GCD of two non-zero integers.
    
    596
    ---
    
    597
    --- I.e. integer_gcde a b returns (g,x,y) so that ax + by = g
    
    598
    ---
    
    599
    --- Input: a and b are non zero.
    
    600
    --- Output: g must be > 0
    
    601
    ---
    
    602
    -integer_gcde
    
    603
    -   :: Integer
    
    604
    -   -> Integer
    
    605
    -   -> (# Integer, Integer, Integer #)
    
    606
    -integer_gcde = Native.integer_gcde
    
    607
    -   -- for now we use Native's implementation. If some FFI backend user needs a
    
    608
    -   -- specific implementation, we'll need to determine a prototype to pass and
    
    609
    -   -- return BigNat signs and sizes via FFI.
    
    610
    -
    
    611
    -
    
    612
    --- | Computes the modular inverse of two non-zero integers.
    
    613
    ---
    
    614
    --- I.e. y = integer_recip_mod x m
    
    615
    ---        = x^(-1) `mod` m
    
    616
    ---
    
    617
    --- with 0 < y < abs m
    
    618
    -integer_recip_mod
    
    619
    -   :: Integer
    
    620
    -   -> Natural
    
    621
    -   -> (# Natural | () #)
    
    622
    -integer_recip_mod = Native.integer_recip_mod
    
    623
    -   -- for now we use Native's implementation. If some FFI backend user needs a
    
    624
    -   -- specific implementation, we'll need to determine a prototype to pass and
    
    625
    -   -- return BigNat signs and sizes via FFI.
    
    626
    -
    
    627
    --- | Computes the modular exponentiation.
    
    628
    ---
    
    629
    --- I.e. y = integer_powmod b e m
    
    630
    ---        = b^e `mod` m
    
    631
    ---
    
    632
    --- with 0 <= y < abs m
    
    633
    -integer_powmod
    
    634
    -   :: Integer
    
    635
    -   -> Natural
    
    636
    -   -> Natural
    
    637
    -   -> Natural
    
    638
    -integer_powmod = Native.integer_powmod
    
    639
    -   -- for now we use Native's implementation. If some FFI backend user needs a
    
    640
    -   -- specific implementation, we'll need to determine a prototype to pass and
    
    641
    -   -- 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
    14 14
     #include "MachDeps.h"
    
    15 15
     #include "WordSize.h"
    
    16 16
     
    
    17
    -#if defined(BIGNUM_NATIVE) || defined(BIGNUM_CHECK) || defined(BIGNUM_FFI)
    
    17
    +#if defined(BIGNUM_NATIVE)
    
    18 18
     import {-# SOURCE #-} GHC.Internal.Bignum.BigNat
    
    19 19
     import {-# SOURCE #-} GHC.Internal.Bignum.Natural
    
    20 20
     import {-# SOURCE #-} GHC.Internal.Bignum.Integer
    
    ... ... @@ -50,6 +50,12 @@ count_words_bits_int :: Word# -> (# Int#, Int# #)
    50 50
     count_words_bits_int n = case count_words_bits n of
    
    51 51
        (# nw, nb #) -> (# word2Int# nw, word2Int# nb #)
    
    52 52
     
    
    53
    +-- | Compare two non-zero BigNat of the same length
    
    54
    +--
    
    55
    +-- Return:
    
    56
    +--     < 0 ==> LT
    
    57
    +--    == 0 ==> EQ
    
    58
    +--     > 0 ==> GT
    
    53 59
     bignat_compare :: WordArray# -> WordArray# -> Int#
    
    54 60
     bignat_compare wa wb = go (sz -# 1#)
    
    55 61
        where
    
    ... ... @@ -62,6 +68,13 @@ bignat_compare wa wb = go (sz -# 1#)
    62 68
                   | isTrue# (a `gtWord#` b) -> 1#
    
    63 69
                   | True                    -> -1#
    
    64 70
     
    
    71
    +-- | Add two non-zero BigNat
    
    72
    +--
    
    73
    +-- Result is to be stored in the MutableWordArray#.
    
    74
    +-- The latter has size: max (size a, size b) + 1
    
    75
    +--
    
    76
    +-- The potential 0 most-significant Word (i.e. the potential carry) will be
    
    77
    +-- removed by the caller if it is not already done by the backend.
    
    65 78
     bignat_add
    
    66 79
        :: MutableWordArray# s -- ^ Result
    
    67 80
        -> WordArray#
    
    ... ... @@ -120,6 +133,13 @@ bignat_add mwa wa wb = addABc 0# 0##
    120 133
                in case mwaWrite# mwa i r s of
    
    121 134
                    s' -> addAoBc wab (i +# 1#) carry' s'
    
    122 135
     
    
    136
    +-- | Add a non-zero BigNat and a non-zero Word#
    
    137
    +--
    
    138
    +-- Result is to be stored in the MutableWordArray#.
    
    139
    +-- The latter has size: size a + 1
    
    140
    +--
    
    141
    +-- The potential 0 most-significant Word (i.e. the potential carry) will be
    
    142
    +-- removed by the caller if it is not already done by the backend.
    
    123 143
     bignat_add_word
    
    124 144
        :: MutableWordArray# RealWorld -- ^ Result
    
    125 145
        -> WordArray#
    
    ... ... @@ -128,6 +148,15 @@ bignat_add_word
    128 148
        -> State# RealWorld
    
    129 149
     bignat_add_word mwa wa b s = mwaInitArrayPlusWord mwa wa b s
    
    130 150
     
    
    151
    +-- | Sub a non-zero word from a non-zero BigNat
    
    152
    +--
    
    153
    +-- Result is to be stored in the MutableWordArray#.
    
    154
    +-- The latter has size: size a
    
    155
    +--
    
    156
    +-- The potential 0 most-significant Words will be removed by the caller if it is
    
    157
    +-- not already done by the backend.
    
    158
    +--
    
    159
    +-- Return False# to indicate underflow.
    
    131 160
     bignat_sub_word
    
    132 161
        :: MutableWordArray# RealWorld
    
    133 162
        -> WordArray#
    
    ... ... @@ -154,6 +183,13 @@ bignat_sub_word mwa wa b = go b 0#
    154 183
                 (# l  , c  #) -> case mwaWrite# mwa i l s of
    
    155 184
                                   s1 -> go (int2Word# c) (i +# 1#) s1
    
    156 185
     
    
    186
    +-- | Multiply a non-zero BigNat and a non-zero Word#
    
    187
    +--
    
    188
    +-- Result is to be stored in the MutableWordArray#.
    
    189
    +-- The latter has size: size a + 1
    
    190
    +--
    
    191
    +-- The potential 0 most-significant Word (i.e. the potential carry) will be
    
    192
    +-- removed by the caller if it is not already done by the backend.
    
    157 193
     bignat_mul_word
    
    158 194
        :: MutableWordArray# RealWorld -- ^ Result
    
    159 195
        -> WordArray#
    
    ... ... @@ -173,6 +209,13 @@ bignat_mul_word mwa wa b = go 0# 0##
    173 209
                       s' -> go (i +# 1#) carry' s'
    
    174 210
     
    
    175 211
     
    
    212
    +-- | Multiply two non-zero BigNat
    
    213
    +--
    
    214
    +-- Result is to be stored in the MutableWordArray#.
    
    215
    +-- The latter has size: size a+size b
    
    216
    +--
    
    217
    +-- The potential 0 most-significant Word (i.e. the potential carry) will be
    
    218
    +-- removed by the caller if it is not already done by the backend.
    
    176 219
     bignat_mul
    
    177 220
        :: MutableWordArray# RealWorld -- ^ Result
    
    178 221
        -> WordArray#
    
    ... ... @@ -214,6 +257,15 @@ bignat_mul mwa wa wb s1 =
    214 257
                 bi  -> case mul mwa wa bi i ctzA 0## s of
    
    215 258
                          s' -> mulEachB (i +# 1#) s'
    
    216 259
     
    
    260
    +-- | Sub two non-zero BigNat
    
    261
    +--
    
    262
    +-- Result is to be stored in the MutableWordArray#.
    
    263
    +-- The latter has size: size a
    
    264
    +--
    
    265
    +-- The potential 0 most-significant Words will be removed by the caller if it is
    
    266
    +-- not already done by the backend.
    
    267
    +--
    
    268
    +-- Return False# to indicate underflow.
    
    217 269
     bignat_sub
    
    218 270
        :: MutableWordArray# RealWorld
    
    219 271
        -> WordArray#
    
    ... ... @@ -227,6 +279,7 @@ bignat_sub mwa wa wb s =
    227 279
        case mwaArrayCopy# mwa 0# wa 0# (wordArraySize# wa) s of
    
    228 280
           s' -> mwaSubInplaceArray mwa 0# wb s'
    
    229 281
     
    
    282
    +-- | PopCount of a non-zero BigNat
    
    230 283
     bignat_popcount :: WordArray# -> Word#
    
    231 284
     bignat_popcount wa = go 0# 0##
    
    232 285
        where
    
    ... ... @@ -235,6 +288,13 @@ bignat_popcount wa = go 0# 0##
    235 288
              | isTrue# (i ==# sz) = c
    
    236 289
              | True               = go (i +# 1#) (c `plusWord#` popCnt# (indexWordArray# wa i))
    
    237 290
     
    
    291
    +-- | Left-shift a non-zero BigNat by a non-zero amount of bits
    
    292
    +--
    
    293
    +-- Result is to be stored in the MutableWordArray#.
    
    294
    +-- The latter has size: size a + required new limbs
    
    295
    +--
    
    296
    +-- The potential 0 most-significant Word (i.e. the potential carry) will be
    
    297
    +-- removed by the caller if it is not already done by the backend.
    
    238 298
     bignat_shiftl
    
    239 299
        :: MutableWordArray# s
    
    240 300
        -> WordArray#
    
    ... ... @@ -267,6 +327,13 @@ bignat_shiftl mwa wa n s1 =
    267 327
                       s' -> mwaBitShift (i +# 1#) c' s'
    
    268 328
     
    
    269 329
     
    
    330
    +-- | Right-shift a non-zero BigNat by a non-zero amount of bits
    
    331
    +--
    
    332
    +-- Result is to be stored in the MutableWordArray#.
    
    333
    +-- The latter has size: required limbs
    
    334
    +--
    
    335
    +-- The potential 0 most-significant Word (i.e. the potential carry) will be
    
    336
    +-- removed by the caller if it is not already done by the backend.
    
    270 337
     bignat_shiftr
    
    271 338
        :: MutableWordArray# s
    
    272 339
        -> WordArray#
    
    ... ... @@ -293,6 +360,15 @@ bignat_shiftr mwa wa n s1
    293 360
                 in case mwaWrite# mwa i v s of
    
    294 361
                       s' -> mwaBitShift (i -# 1#) c' s'
    
    295 362
     
    
    363
    +-- | Right-shift a non-zero BigNat by a non-zero amount of bits by first
    
    364
    +-- converting it into its two's complement representation and then again after
    
    365
    +-- the arithmetic shift.
    
    366
    +--
    
    367
    +-- Result is to be stored in the MutableWordArray#.
    
    368
    +-- The latter has size: required limbs
    
    369
    +--
    
    370
    +-- The potential 0 most-significant Words (i.e. the potential carry) will be
    
    371
    +-- removed by the caller if it is not already done by the backend.
    
    296 372
     bignat_shiftr_neg
    
    297 373
        :: MutableWordArray# s
    
    298 374
        -> WordArray#
    
    ... ... @@ -329,6 +405,10 @@ bignat_shiftr_neg mwa wa n s1
    329 405
                in go 0#
    
    330 406
     
    
    331 407
     
    
    408
    +-- | OR two non-zero BigNat
    
    409
    +--
    
    410
    +-- Result is to be stored in the MutableWordArray#.
    
    411
    +-- The latter has size: max (size a, size b)
    
    332 412
     bignat_or
    
    333 413
        :: MutableWordArray# RealWorld -- ^ Result
    
    334 414
        -> WordArray#
    
    ... ... @@ -346,6 +426,13 @@ bignat_or mwa wa wb s1
    346 426
              case mwaInitArrayBinOp mwa wx wy or# s of
    
    347 427
                 s' -> mwaArrayCopy# mwa ny wx ny (nx -# ny) s'
    
    348 428
     
    
    429
    +-- | XOR two non-zero BigNat
    
    430
    +--
    
    431
    +-- Result is to be stored in the MutableWordArray#.
    
    432
    +-- The latter has size: max (size a, size b)
    
    433
    +--
    
    434
    +-- The potential 0 most-significant Words will be removed by the caller if it is
    
    435
    +-- not already done by the backend.
    
    349 436
     bignat_xor
    
    350 437
        :: MutableWordArray# RealWorld -- ^ Result
    
    351 438
        -> WordArray#
    
    ... ... @@ -363,6 +450,13 @@ bignat_xor mwa wa wb s1
    363 450
              case mwaInitArrayBinOp mwa wx wy xor# s of
    
    364 451
                 s' -> mwaArrayCopy# mwa ny wx ny (nx -# ny) s'
    
    365 452
     
    
    453
    +-- | AND two non-zero BigNat
    
    454
    +--
    
    455
    +-- Result is to be stored in the MutableWordArray#.
    
    456
    +-- The latter has size: min (size a, size b)
    
    457
    +--
    
    458
    +-- The potential 0 most-significant Words will be removed by the caller if it is
    
    459
    +-- not already done by the backend.
    
    366 460
     bignat_and
    
    367 461
        :: MutableWordArray# RealWorld -- ^ Result
    
    368 462
        -> WordArray#
    
    ... ... @@ -371,6 +465,13 @@ bignat_and
    371 465
        -> State# RealWorld
    
    372 466
     bignat_and mwa wa wb s = mwaInitArrayBinOp mwa wa wb and# s
    
    373 467
     
    
    468
    +-- | ANDNOT two non-zero BigNat
    
    469
    +--
    
    470
    +-- Result is to be stored in the MutableWordArray#.
    
    471
    +-- The latter has size: size a
    
    472
    +--
    
    473
    +-- The potential 0 most-significant Words will be removed by the caller if it is
    
    474
    +-- not already done by the backend.
    
    374 475
     bignat_and_not
    
    375 476
        :: MutableWordArray# RealWorld -- ^ Result
    
    376 477
        -> WordArray#
    
    ... ... @@ -384,9 +485,17 @@ bignat_and_not mwa wa wb s =
    384 485
           !szA = wordArraySize# wa
    
    385 486
           !szB = wordArraySize# wb
    
    386 487
     
    
    488
    +-- | QuotRem of two non-zero BigNat
    
    489
    +--
    
    490
    +-- Result quotient and remainder are to be stored in the MutableWordArray#.
    
    491
    +-- The first one (quotient) has size: size(A)-size(B)+1
    
    492
    +-- The second one (remainder) has size: size(b)
    
    493
    +--
    
    494
    +-- The potential 0 most-significant Words will be removed by the caller if it is
    
    495
    +-- not already done by the backend.
    
    387 496
     bignat_quotrem
    
    388
    -   :: MutableWordArray# s
    
    389
    -   -> MutableWordArray# s
    
    497
    +   :: MutableWordArray# s -- ^ Quotient
    
    498
    +   -> MutableWordArray# s -- ^ Remainder
    
    390 499
        -> WordArray#
    
    391 500
        -> WordArray#
    
    392 501
        -> State# s
    
    ... ... @@ -434,8 +543,15 @@ bignat_quotrem mwq mwr uwa uwb s0 =
    434 543
     
    
    435 544
     
    
    436 545
     
    
    546
    +-- | Quotient of two non-zero BigNat
    
    547
    +--
    
    548
    +-- Result quotient is to be stored in the MutableWordArray#.
    
    549
    +-- The latter has size: size(A)-size(B)+1
    
    550
    +--
    
    551
    +-- The potential 0 most-significant Words will be removed by the caller if it is
    
    552
    +-- not already done by the backend.
    
    437 553
     bignat_quot
    
    438
    -   :: MutableWordArray# RealWorld
    
    554
    +   :: MutableWordArray# RealWorld -- ^ Quotient
    
    439 555
        -> WordArray#
    
    440 556
        -> WordArray#
    
    441 557
        -> State# RealWorld
    
    ... ... @@ -445,8 +561,15 @@ bignat_quot mwq wa wb s =
    445 561
        case newWordArray# (wordArraySize# wb) s of
    
    446 562
           (# s, mwr #) -> bignat_quotrem mwq mwr wa wb s
    
    447 563
     
    
    564
    +-- | Remainder of two non-zero BigNat
    
    565
    +--
    
    566
    +-- Result remainder is to be stored in the MutableWordArray#.
    
    567
    +-- The latter has size: size(B)
    
    568
    +--
    
    569
    +-- The potential 0 most-significant Words will be removed by the caller if it is
    
    570
    +-- not already done by the backend.
    
    448 571
     bignat_rem
    
    449
    -   :: MutableWordArray# RealWorld
    
    572
    +   :: MutableWordArray# RealWorld -- ^ Remainder
    
    450 573
        -> WordArray#
    
    451 574
        -> WordArray#
    
    452 575
        -> State# RealWorld
    
    ... ... @@ -577,6 +700,15 @@ bignat_quotrem_normalized mwq mwa b s0 =
    577 700
              | True    -> loop (m -# 1#) s2
    
    578 701
        }}
    
    579 702
     
    
    703
    +-- | QuotRem of a non-zero BigNat and a non-zero Word
    
    704
    +--
    
    705
    +-- Result quotient is to be stored in the MutableWordArray#.
    
    706
    +-- The latter has size: size(A)
    
    707
    +--
    
    708
    +-- The remainder is returned.
    
    709
    +--
    
    710
    +-- The potential 0 most-significant Words will be removed by the caller if it is
    
    711
    +-- not already done by the backend.
    
    580 712
     bignat_quotrem_word
    
    581 713
        :: MutableWordArray# s -- ^ Quotient
    
    582 714
        -> WordArray#
    
    ... ... @@ -595,6 +727,13 @@ bignat_quotrem_word mwq wa b s = go (sz -# 1#) 0## s
    595 727
                 in case mwaWrite# mwq i q s of
    
    596 728
                       s' -> go (i -# 1#) r' s'
    
    597 729
     
    
    730
    +-- | Quot of a non-zero BigNat and a non-zero Word
    
    731
    +--
    
    732
    +-- Result quotient is to be stored in the MutableWordArray#.
    
    733
    +-- The latter has size: size(A)
    
    734
    +--
    
    735
    +-- The potential 0 most-significant Words will be removed by the caller if it is
    
    736
    +-- not already done by the backend.
    
    598 737
     bignat_quot_word
    
    599 738
        :: MutableWordArray# s -- ^ Quotient
    
    600 739
        -> WordArray#
    
    ... ... @@ -613,6 +752,9 @@ bignat_quot_word mwq wa b s = go (sz -# 1#) 0## s
    613 752
                 in case mwaWrite# mwq i q s of
    
    614 753
                       s' -> go (i -# 1#) r' s'
    
    615 754
     
    
    755
    +-- | Remainder of a non-zero BigNat and a non-zero Word
    
    756
    +--
    
    757
    +-- The remainder is returned.
    
    616 758
     bignat_rem_word
    
    617 759
        :: WordArray#
    
    618 760
        -> Word#
    
    ... ... @@ -629,6 +771,14 @@ bignat_rem_word wa b = go (sz -# 1#) 0##
    629 771
                 in go (i -# 1#) r'
    
    630 772
     
    
    631 773
     
    
    774
    +-- | Greatest common divisor (GCD) of two non-zero and non-one BigNat
    
    775
    +--
    
    776
    +-- Result GCD is to be stored in the MutableWordArray#.
    
    777
    +-- The latter has size: size(B)
    
    778
    +-- The first WordArray# is greater than the second WordArray#.
    
    779
    +--
    
    780
    +-- The potential 0 most-significant Words will be removed by the caller if it is
    
    781
    +-- not already done by the backend.
    
    632 782
     bignat_gcd
    
    633 783
        :: MutableWordArray# s
    
    634 784
        -> WordArray#
    
    ... ... @@ -647,13 +797,21 @@ bignat_gcd mwr = go
    647 797
                  !wmin' = bigNatRem wmax wmin
    
    648 798
                in go wmax' wmin' s
    
    649 799
     
    
    800
    +-- | Greatest common divisor (GCD) of a non-zero/non-one BigNat and a
    
    801
    +-- non-zero/non-one Word#
    
    802
    +--
    
    803
    +-- Result GCD is returned
    
    650 804
     bignat_gcd_word
    
    651 805
        :: WordArray#
    
    652 806
        -> Word#
    
    653 807
        -> Word#
    
    654 808
     bignat_gcd_word a b = bignat_gcd_word_word b (bigNatRemWord# a b)
    
    655 809
     
    
    656
    --- | This operation doesn't really belongs here, but GMP's one is much faster
    
    810
    +-- | Greatest common divisor (GCD) of two Word#
    
    811
    +--
    
    812
    +-- Result GCD is returned.
    
    813
    +--
    
    814
    +-- This operation doesn't really belongs here, but GMP's one is much faster
    
    657 815
     -- than this simple implementation (basic Euclid algorithm).
    
    658 816
     --
    
    659 817
     -- Ideally we should make an implementation as fast as GMP's one and put it into
    
    ... ... @@ -665,6 +823,7 @@ bignat_gcd_word_word
    665 823
     bignat_gcd_word_word a 0## = a
    
    666 824
     bignat_gcd_word_word a b   = bignat_gcd_word_word b (a `remWord#` b)
    
    667 825
     
    
    826
    +-- | Encode (# BigNat mantissa, Int# exponent #) into a Double#
    
    668 827
     bignat_encode_double :: WordArray# -> Int# -> Double#
    
    669 828
     bignat_encode_double wa e0 = go 0.0## e0 0#
    
    670 829
        where
    
    ... ... @@ -676,6 +835,12 @@ bignat_encode_double wa e0 = go 0.0## e0 0#
    676 835
                   (e +# WORD_SIZE_IN_BITS#) -- FIXME: we assume that e doesn't overflow...
    
    677 836
                   (i +# 1#)
    
    678 837
     
    
    838
    +-- | \"@'bignat_powmod_word' /b/ /e/ /m/@\" computes base @/b/@ raised to
    
    839
    +-- exponent @/e/@ modulo @/m/@.
    
    840
    +--
    
    841
    +-- b > 1
    
    842
    +-- e > 0
    
    843
    +-- m > 1
    
    679 844
     bignat_powmod_word :: WordArray# -> WordArray# -> Word# -> Word#
    
    680 845
     bignat_powmod_word b0 e0 m = go (naturalFromBigNat# b0) (naturalFromBigNat# e0) (naturalFromWord# 1##)
    
    681 846
        where
    
    ... ... @@ -693,6 +858,18 @@ bignat_powmod_word b0 e0 m = go (naturalFromBigNat# b0) (naturalFromBigNat# e0)
    693 858
               m' = naturalFromWord# m
    
    694 859
               e' = e `naturalShiftR#` 1## -- slightly faster than "e `div` 2"
    
    695 860
     
    
    861
    +-- | \"@'bignat_powmod' r /b/ /e/ /m/@\" computes base @/b/@ raised to
    
    862
    +-- exponent @/e/@ modulo @/m/@.
    
    863
    +--
    
    864
    +-- b > 1
    
    865
    +-- e > 0
    
    866
    +-- m > 1
    
    867
    +--
    
    868
    +-- Result is to be stored in the MutableWordArray# (which size is equal to the
    
    869
    +-- one of m).
    
    870
    +--
    
    871
    +-- The potential 0 most-significant Words will be removed by the caller if it is
    
    872
    +-- not already done by the backend.
    
    696 873
     bignat_powmod
    
    697 874
        :: MutableWordArray# RealWorld
    
    698 875
        -> WordArray#
    
    ... ... @@ -720,6 +897,12 @@ bignat_powmod r b0 e0 m s = mwaInitCopyShrink# r r' s
    720 897
               m' = naturalFromBigNat# m
    
    721 898
               e' = e `naturalShiftR#` 1## -- slightly faster than "e `div` 2"
    
    722 899
     
    
    900
    +-- | \"@'bignat_powmod' /b/ /e/ /m/@\" computes base @/b/@ raised to
    
    901
    +-- exponent @/e/@ modulo @/m/@.
    
    902
    +--
    
    903
    +-- b > 1
    
    904
    +-- e > 0
    
    905
    +-- m > 1
    
    723 906
     bignat_powmod_words
    
    724 907
        :: Word#
    
    725 908
        -> Word#
    
    ... ... @@ -731,6 +914,13 @@ bignat_powmod_words b e m =
    731 914
                           m
    
    732 915
     
    
    733 916
     
    
    917
    +-- | Return extended GCD of two non-zero integers.
    
    918
    +--
    
    919
    +-- I.e. integer_gcde a b returns (g,x,y) so that ax + by = g
    
    920
    +--
    
    921
    +-- Input: a and b are non zero.
    
    922
    +-- Output: g must be > 0
    
    923
    +--
    
    734 924
     integer_gcde
    
    735 925
        :: Integer
    
    736 926
        -> Integer
    
    ... ... @@ -748,6 +938,12 @@ integer_gcde a b = f (# a,integerOne,integerZero #) (# b,integerZero,integerOne
    748 938
                                   !(# q, r #) -> f new (# r , old_s `integerSub` (q `integerMul` s)
    
    749 939
                                                             , old_t `integerSub` (q `integerMul` t) #)
    
    750 940
     
    
    941
    +-- | Computes the modular inverse of two non-zero integers.
    
    942
    +--
    
    943
    +-- I.e. y = integer_recip_mod x m
    
    944
    +--        = x^(-1) `mod` m
    
    945
    +--
    
    946
    +-- with 0 < y < abs m
    
    751 947
     integer_recip_mod
    
    752 948
        :: Integer
    
    753 949
        -> Natural
    
    ... ... @@ -763,6 +959,12 @@ integer_recip_mod x m =
    763 959
                                            -- a `mod` m > 0 because m > 0
    
    764 960
              | True                     -> (# | () #)
    
    765 961
     
    
    962
    +-- | Computes the modular exponentiation.
    
    963
    +--
    
    964
    +-- I.e. y = integer_powmod b e m
    
    965
    +--        = b^e `mod` m
    
    966
    +--
    
    967
    +-- with 0 <= y < abs m
    
    766 968
     integer_powmod
    
    767 969
        :: Integer
    
    768 970
        -> Natural
    

  • libraries/ghc-internal/src/GHC/Internal/Bignum/Backend/Selected.hs deleted
    1
    -{-# LANGUAGE CPP #-}
    
    2
    -{-# LANGUAGE NoImplicitPrelude #-}
    
    3
    -
    
    4
    --- | Selected backend
    
    5
    ---
    
    6
    --- We need this module in addition to GHC.Internal.Bignum.Backend to avoid module loops with
    
    7
    --- Check backend.
    
    8
    -module GHC.Internal.Bignum.Backend.Selected
    
    9
    -   ( module Backend
    
    10
    -   )
    
    11
    -where
    
    12
    -
    
    13
    -#if defined(BIGNUM_NATIVE)
    
    14
    -import GHC.Internal.Bignum.Backend.Native as Backend
    
    15
    -
    
    16
    -#elif defined(BIGNUM_FFI)
    
    17
    -import GHC.Internal.Bignum.Backend.FFI as Backend
    
    18
    -
    
    19
    -#elif defined(BIGNUM_GMP)
    
    20
    -import GHC.Internal.Bignum.Backend.GMP as Backend
    
    21
    -
    
    22
    -#else
    
    23
    -#error Undefined BigNum backend. Use a flag to select it (e.g. gmp, native, ffi)`
    
    24
    -#endif

  • rts/sm/BlockAlloc.c
    ... ... @@ -549,6 +549,8 @@ allocGroupOnNode (uint32_t node, W_ n)
    549 549
             ln++;
    
    550 550
         }
    
    551 551
     
    
    552
    +    // If no free blocks exist then allocate a new megablock and keep just a
    
    553
    +    // chunk of it.
    
    552 554
         if (ln == NUM_FREE_LISTS) {
    
    553 555
     #if 0  /* useful for debugging fragmentation */
    
    554 556
             if ((W_)mblocks_allocated * BLOCKS_PER_MBLOCK * BLOCK_SIZE_W
    
    ... ... @@ -1020,6 +1022,9 @@ freeGroup(bdescr *p)
    1020 1022
       }
    
    1021 1023
     
    
    1022 1024
       // coalesce backwards
    
    1025
    +  // Note that p is not a megablock/megagroup, so there are still live blocks on
    
    1026
    +  // this megablock. Hence we can't coalesce backwards past the first block
    
    1027
    +  // descriptor of this megablock.
    
    1023 1028
       if (p != FIRST_BDESCR(MBLOCK_ROUND_DOWN(p)))
    
    1024 1029
       {
    
    1025 1030
           bdescr *prev;
    

  • rts/sm/MBlock.c
    ... ... @@ -95,6 +95,10 @@ typedef struct free_list {
    95 95
     } free_list;
    
    96 96
     
    
    97 97
     static free_list *free_list_head;
    
    98
    +
    
    99
    +// The address in `mblock_address_space` just after the highest MBlock. This
    
    100
    +// will be the address of the next new MBlock committed when the free list is
    
    101
    +// empty.
    
    98 102
     static W_ mblock_high_watermark;
    
    99 103
     /*
    
    100 104
      * it is quite important that these are in the same cache line as they
    
    ... ... @@ -103,22 +107,47 @@ static W_ mblock_high_watermark;
    103 107
      */
    
    104 108
     struct mblock_address_range mblock_address_space = { 0, 0, {} };
    
    105 109
     
    
    110
    +// Search for the first committed MBlock at or after startingAt.
    
    111
    +//
    
    112
    +// start_iter [in/out]: The free_list or a subset of it. Must contain all
    
    113
    +// entries for MBlocks at or after startingAt. On return this is set to the
    
    114
    +// free_list entry just after the returned MBlock. If no MBlock was found, This
    
    115
    +// is set to NULL (the search will have reached the end of the free list).
    
    116
    +//
    
    117
    +// startingAt [in]: address from which to start searching. This must be to the
    
    118
    +// start of an MBlock.
    
    119
    +//
    
    120
    +// return: The address of the committed MBlock. NULL if no committed MBLock was
    
    121
    +// found.
    
    122
    +//
    
    106 123
     static void *getAllocatedMBlock(free_list **start_iter, W_ startingAt)
    
    107 124
     {
    
    125
    +    // We simultaneously traverse the free list and the mblock_address_space.
    
    108 126
         free_list *iter;
    
    109 127
         W_ p = startingAt;
    
    110 128
     
    
    111 129
         for (iter = *start_iter; iter != NULL; iter = iter->next)
    
    112 130
         {
    
    131
    +        // The current free MBlock, `iter`, is past the current MBlock, `p`.
    
    132
    +        // This means that `p` is committed (if it was free, then we would have
    
    133
    +        // found it on the free list). Stop searching.
    
    113 134
             if (p < iter->address)
    
    114 135
                 break;
    
    115 136
     
    
    137
    +        // Note that if `p > iter->address`, then we don't bump `p`. This just
    
    138
    +        // means we are skipping entries in the free list that correspond to
    
    139
    +        // MBlocks before `startingAt`.
    
    116 140
             if (p == iter->address)
    
    141
    +            // Move to the next MBlock. The MBlock may be committed,
    
    142
    +            // uncommitted, or even past mblock_high_watermark.
    
    117 143
                 p += iter->size;
    
    118 144
         }
    
    119 145
     
    
    146
    +    // Output current free list entry.
    
    120 147
         *start_iter = iter;
    
    121 148
     
    
    149
    +    // If we reached mblock_high_watermark, then we didn't find any committed
    
    150
    +    // MBlocks.
    
    122 151
         if (p >= mblock_high_watermark)
    
    123 152
             return NULL;
    
    124 153
     
    
    ... ... @@ -152,6 +181,11 @@ void * getNextMBlock(void **state STG_UNUSED, void *mblock)
    152 181
         return getAllocatedMBlock(casted_state, (W_)mblock + MBLOCK_SIZE);
    
    153 182
     }
    
    154 183
     
    
    184
    +// Used to implement getCommittedMBlocks. Search the free list for n contiguous
    
    185
    +// free MBlocks, and commit those MBlocks, updating the free_list. Returns the
    
    186
    +// address of the start of those MBlocks. Returns NULL if no n contiguous
    
    187
    +// MBlocks were found in the free list. Unlike getFreshMBlocks, this doesn't
    
    188
    +// attempt to allocate new MBlocks past mblock_high_watermark.
    
    155 189
     static void *getReusableMBlocks(uint32_t n)
    
    156 190
     {
    
    157 191
         struct free_list *iter;
    
    ... ... @@ -163,7 +197,10 @@ static void *getReusableMBlocks(uint32_t n)
    163 197
             if (iter->size < size)
    
    164 198
                 continue;
    
    165 199
     
    
    200
    +        // We've found a large enough group of MBlocks.
    
    166 201
             addr = (void*)iter->address;
    
    202
    +
    
    203
    +        // Update the free list.
    
    167 204
             iter->address += size;
    
    168 205
             iter->size -= size;
    
    169 206
             if (iter->size == 0) {
    
    ... ... @@ -190,6 +227,9 @@ static void *getReusableMBlocks(uint32_t n)
    190 227
         return NULL;
    
    191 228
     }
    
    192 229
     
    
    230
    +// Used to implement getCommittedMBlocks. Commit n new MBlocks starting at
    
    231
    +// mblock_high_watermark. May exit with an out of memory error if we've passed
    
    232
    +// mblock_address_space.end (this is unlikely).
    
    193 233
     static void *getFreshMBlocks(uint32_t n)
    
    194 234
     {
    
    195 235
         W_ size = MBLOCK_SIZE * (W_)n;
    
    ... ... @@ -207,6 +247,8 @@ static void *getFreshMBlocks(uint32_t n)
    207 247
         return addr;
    
    208 248
     }
    
    209 249
     
    
    250
    +// Commit n new MBlocks. Tries to reuse freed MBlocks, else commits new
    
    251
    +// MBlock(s) at mblock_high_watermark.
    
    210 252
     static void *getCommittedMBlocks(uint32_t n)
    
    211 253
     {
    
    212 254
         void *p;
    
    ... ... @@ -220,6 +262,11 @@ static void *getCommittedMBlocks(uint32_t n)
    220 262
         return p;
    
    221 263
     }
    
    222 264
     
    
    265
    +// Decommit n contiguous MBlocks starting at the given address.
    
    266
    +//
    
    267
    +// addr [in]: address of the start of the n MBlocks (in mblock_address_space).
    
    268
    +//
    
    269
    +// n [in]: number of contiguous MBlocks to decommit.
    
    223 270
     static void decommitMBlocks(char *addr, uint32_t n)
    
    224 271
     {
    
    225 272
         struct free_list *iter, *prev;
    
    ... ... @@ -228,17 +275,24 @@ static void decommitMBlocks(char *addr, uint32_t n)
    228 275
     
    
    229 276
         osDecommitMemory(addr, size);
    
    230 277
     
    
    278
    +    // Update the free list.
    
    231 279
         prev = NULL;
    
    232 280
         for (iter = free_list_head; iter != NULL; iter = iter->next)
    
    233 281
         {
    
    234 282
             prev = iter;
    
    235 283
     
    
    284
    +        // iter is still entirely behind and not contiguous with the MBlocks so
    
    285
    +        // continue traversing free_list.
    
    236 286
             if (iter->address + iter->size < address)
    
    237 287
                 continue;
    
    238 288
     
    
    289
    +        // The MBlocks are after and contiguous to iter. Simply modify the
    
    290
    +        // current entry to include n more MBlocks and possibly coalesce.
    
    239 291
             if (iter->address + iter->size == address) {
    
    240 292
                 iter->size += size;
    
    241 293
     
    
    294
    +            // If the current free_list entry now reaches mblock_high_watermark,
    
    295
    +            // remove the entry and decrement mblock_high_watermark.
    
    242 296
                 if (address + size == mblock_high_watermark) {
    
    243 297
                     mblock_high_watermark -= iter->size;
    
    244 298
                     if (iter->prev) {
    
    ... ... @@ -251,6 +305,8 @@ static void decommitMBlocks(char *addr, uint32_t n)
    251 305
                     return;
    
    252 306
                 }
    
    253 307
     
    
    308
    +            // If the current free_list entry now reaches the next free_list
    
    309
    +            // entry, coalesce them.
    
    254 310
                 if (iter->next &&
    
    255 311
                     iter->next->address == iter->address + iter->size) {
    
    256 312
                     struct free_list *next;
    
    ... ... @@ -269,6 +325,8 @@ static void decommitMBlocks(char *addr, uint32_t n)
    269 325
                     stgFree(next);
    
    270 326
                 }
    
    271 327
                 return;
    
    328
    +
    
    329
    +        // The MBlocks are before and contiguous to iter.
    
    272 330
             } else if (address + size == iter->address) {
    
    273 331
                 iter->address = address;
    
    274 332
                 iter->size += size;
    
    ... ... @@ -280,6 +338,9 @@ static void decommitMBlocks(char *addr, uint32_t n)
    280 338
                     ASSERT(iter->prev->address + iter->prev->size < iter->address);
    
    281 339
                 }
    
    282 340
                 return;
    
    341
    +
    
    342
    +        // The MBlocks are before and not contiguous to iter. Insert a new entry
    
    343
    +        // just before iter.
    
    283 344
             } else {
    
    284 345
                 struct free_list *new_iter;
    
    285 346
     
    
    ... ... @@ -311,6 +372,7 @@ static void decommitMBlocks(char *addr, uint32_t n)
    311 372
         if (address + size == mblock_high_watermark) {
    
    312 373
             mblock_high_watermark -= size;
    
    313 374
         } else {
    
    375
    +        // Add a new entry to the end of the free list.
    
    314 376
             struct free_list *new_iter;
    
    315 377
     
    
    316 378
             new_iter = stgMallocBytes(sizeof(struct free_list), "freeMBlocks");
    

  • rts/win32/libHSghc-internal.def.in
    1
    -LIBRARY libHSghc-internal-@ProjectVersionForLib@.0-ghc@ProjectVersion@.dll
    
    1
    +LIBRARY @GhcInternalDll@
    
    2 2
     
    
    3 3
     EXPORTS
    
    4 4
         init_ghc_hs_iface