Commit 9f96bc12 authored by Sylvain Henry's avatar Sylvain Henry Committed by Ben Gamari

ghc-bignum library

ghc-bignum is a newer package that aims to replace the legacy
integer-simple and integer-gmp packages.

* it supports several backends. In particular GMP is still supported and
  most of the code from integer-gmp has been merged in the "gmp"
  backend.

* the pure Haskell "native" backend is new and is much faster than the
  previous pure Haskell implementation provided by integer-simple

* new backends are easier to write because they only have to provide a
  few well defined functions. All the other code is common to all
  backends. In particular they all share the efficient small/big number
  distinction previously used only in integer-gmp.

* backends can all be tested against the "native" backend with a simple
  Cabal flag. Backends are only allowed to differ in performance, their
  results should be the same.

* Add `integer-gmp` compat package: provide some pattern synonyms and
  function aliases for those in `ghc-bignum`. It is intended to avoid
  breaking packages that depend on `integer-gmp` internals.

Update submodules: text, bytestring

Metric Decrease:
    Conversions
    ManyAlternatives
    ManyConstructors
    Naperian
    T10359
    T10547
    T10678
    T12150
    T12227
    T12234
    T12425
    T13035
    T13719
    T14936
    T1969
    T4801
    T4830
    T5237
    T5549
    T5837
    T8766
    T9020
    parsing001
    space_leak_001
    T16190
    haddock.base

On ARM and i386, T17499 regresses (+6% > 5%).
On x86_64 unregistered, T13701 sometimes regresses (+2.2% > 2%).

Metric Increase:
    T17499
    T13701
parent 57db91d8
......@@ -105,7 +105,7 @@
url = https://gitlab.haskell.org/ghc/libffi-tarballs.git
ignore = untracked
[submodule "gmp-tarballs"]
path = libraries/integer-gmp/gmp/gmp-tarballs
path = libraries/ghc-bignum/gmp/gmp-tarballs
url = https://gitlab.haskell.org/ghc/gmp-tarballs.git
[submodule "libraries/exceptions"]
path = libraries/exceptions
......
......@@ -854,7 +854,7 @@ When you compile a simple module that contains Template Haskell splice
a = ()
$(return [])
$(return [])
with the compiler flags ``-fplugin SourcePlugin`` it will give the following
output:
......@@ -865,16 +865,12 @@ output:
module A where
a = ()
$(return [])
interface loaded: Prelude
interface loaded: GHC.Float
interface loaded: GHC.Base
typeCheckPlugin (rn): a = ()
interface loaded: Language.Haskell.TH.Lib.Internal
interface loaded: Language.Haskell.TH.Syntax
interface loaded: GHC.Types
meta: return []
interface loaded: GHC.Integer.Type
typeCheckPlugin (rn):
Just a = ()
typeCheckPlugin (rn):
Nothing
typeCheckPlugin (tc):
{$trModule = Module (TrNameS "main"#) (TrNameS "A"#), a = ()}
......
GMP
===
integer-gmp depends on the external GMP library (gmplib.org). The latter
provides a header ("gmp.h") and a library to link with.
ghc-bignum's GMP backend depends on the external GMP library (gmplib.org). The
latter provides a header ("gmp.h") and a library to link with.
Linking
-------
Sadly we can't just put a ``extra-libraries: gmp`` field in the Cabal file because
``integer-gmp`` is a boot package that is part of GHC's *binary* distribution.
``ghc-bignum`` is a boot package that is part of GHC's *binary* distribution.
It means that it won't be rebuilt on each user platform. In particular it can be
used in an environment that doesn't provide GMP.
A solution would be to always link GMP statically with ``integer-gmp``, but:
A solution would be to always link GMP statically with ``ghc-bignum``, but:
1. GMP's license is LPGL while GHC's license is BSD
......@@ -32,7 +32,7 @@ As Cabal can't statically link an external library with a Haskell library,
GHC's build system uses a hack:
1. it builds libgmp.a
2. it extracts the objects (.o) from it
3. it passes these objects as "extra" objects when it links integer-gmp
3. it passes these objects as "extra" objects when it links ghc-bignum
Note that these objects must be built as position independent code (PIC) because
they end up being used in statically and dynamically linked code (cf #17799).
......@@ -45,19 +45,20 @@ GMP is linked:
.. code::
--with-gmp enable GMP backend
--with-gmp-includes directory containing gmp.h
--with-gmp-libraries directory containing gmp library
--with-intree-gmp force using the in-tree GMP
--with-gmp-framework-preferred on OSX, prefer the GMP framework to the gmp lib
These options are then used when integer-gmp package is configured: in the
These options are then used when ghc-bignum package is configured: in the
.cabal file, we can see the field ``build-type: Configure``, meaning that the
``configure`` script in ``libraries/integer-gmp/`` is executed during the setup
``configure`` script in ``libraries/ghc-bignum/`` is executed during the setup
phase of the package.
This script is responsible of creating ``integer-gmp.buildinfo`` (from
``integer-gmp.buildinfo.in``). The fields contained in this file are
merged with the ones already defined in ``integer-gmp.cabal``.
This script is responsible of creating ``ghc-bignum.buildinfo`` (from
``ghc-bignum.buildinfo.in``). The fields contained in this file are
merged with the ones already defined in ``ghc-bignum.cabal``.
See
https://www.haskell.org/cabal/users-guide/developing-packages.html#system-dependent-parameters.
......@@ -65,10 +66,10 @@ https://www.haskell.org/cabal/users-guide/developing-packages.html#system-depend
Headers
-------
When GMP is statically linked (in-tree build), a user of the integer-gmp package
When GMP is statically linked (in-tree build), a user of the ghc-bignum package
can't have access to the "gmp.h" header file. So GHC's build system copies the
``ghc.h`` header from the in-tree build to ``integer-gmp/include/ghc-gmp.h``. As you
can see in ``integer-gmp.buildinfo[.in]``, ``ghc-gmp.h`` is installed as a
``ghc.h`` header from the in-tree build to ``ghc-bignum/include/ghc-gmp.h``. As you
can see in ``ghc-bignum.buildinfo[.in]``, ``ghc-gmp.h`` is installed as a
header (``install-includes`` field).
While the commit that introduced it (a9a0dd34dcdfb7309f57bda88435acca14ec54d5)
......@@ -77,4 +78,4 @@ doesn't document it, it's probably to get access to other GMP functions.
Note that when in-tree GMP build isn't used, ``ghc-gmp.h`` only contains
``#include <gmp.h>``. Hence it imports the header from the HOST platform, which
may not be exactly the same as the one used on the BUILD platform to build the
integer-gmp package.
ghc-bignum package.
The Glasgow Haskell Compiler License
Copyright 2020, The University Court of the University of Glasgow.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
- Neither name of the University nor the names of its contributors may be
used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
GHC BIGNUM LIBRARY
==================
This package contains the implementation of the infinite precision integral
types ("big numbers/bignum"):
* BigNat: a positive natural represented as an array of Word# in memory
* Natural: a positive natural represented either by a Word# or by a BigNat
* Integer: a signed integer represented either by an Int# or in sign-magnitude
representation where the magnitude is represented by a BigNat
Natural and Integer have each two representations:
* a small one: Word# or Int# respectively
* a large one: based on BigNat
The small representation is used when the number fits in it. We do this because
GHC is very good at optimizing codes which use Word#/Int# representations
(e.g. storing the number in registers instead of in memory).
Backends
--------
Several backends providing the implementation of some BigNat operations are
supported:
* GMP: based on the `GNU Multiple Precision Arithmetic library
<https://gmplib.org/>`_ library (adapted from the legacy integer-gmp package)
* Native: a pure Haskell implementation written from scratch by Sylvain Henry.
It replaces the previous pure Haskell implementation provided by the
integer-simple package. The major difference is that it uses a much more
efficient memory representation (integer-simple was based on Haskell lists)
and that it allows a lot more code sharing between the different backends than
was previously possible between integer-gmp and integer-simple.
* FFI: an implementation that relies on external FFI calls. This backend can be
useful:
* for alternative GHC backends that target non native platforms (JavaScript,
JVM, etc.): the backend can dynamically match and rewrite the FFI calls in
order to call the appropriate platform specific BigNum API.
* to test new native backends: just tweak the ghc-bignum build to link with
the native library providing the implementation of the FFI calls
Note that the FFI backend module contains the description of the interface
that needs to be implemented by every backend.
This package has been designed to make the implementation of new backends
relatively easy. Previously you had to implement the whole Integer/Natural
interface, to create a new package, etc. Now everything is well contained and
you only have to implement a small part of the BigNat interface. If you want to
try to implement a new backend, you don't have to implement the whole interface
upfront as you can always use the implementation provided by the Native backend
as a fall back.
Avoiding `patError`
-------------------
ghc-bignum is below `base` package. Hence if we use the natural set of
definitions for functions, e.g.:
integerXor (IS x) y = ...
integerXor x (IS y) = ...
integerXor ...
then GHC may not be smart enough (especially when compiling with -O0)
to see that all the cases are handled, and will thus insert calls to
`base:Control.Exception.Base.patError`. But we are below `base` in the
package hierarchy, so this causes link failure!
We therefore help GHC out, by being more explicit about what all the
cases are:
integerXor a b = case a of
IS x -> case b of
IS y -> ...
IN y -> ...
...
/*
* `integer-gmp` GMP FFI wrappers
* `ghc-bignum` GMP FFI wrappers
*
* Copyright (c) 2014, Herbert Valerio Riedel <hvr@gnu.org>
*
......
# Changelog for `ghc-bignum` package
# NB: This file lives in the top-level integer-gmp folder, and not in
# NB: This file lives in the top-level ghc-bignum folder, and not in
# the gmp subfolder, because of #14972, where we MUST NOT create a
# folder named 'gmp' in dist/build/
......
AC_PREREQ(2.69)
AC_INIT([Haskell integer (GMP)], [1.0], [libraries@haskell.org], [integer])
AC_INIT([GHC BigNum library], [1.0], [libraries@haskell.org], [ghc-bignum])
# Safety check: Ensure that we are in the correct source directory.
AC_CONFIG_SRCDIR([cbits/wrappers.c])
AC_CONFIG_SRCDIR([cbits/gmp_wrappers.c])
AC_CANONICAL_TARGET
......@@ -15,6 +15,12 @@ dnl--------------------------------------------------------------------
dnl * Deal with arguments telling us gmp is somewhere odd
dnl--------------------------------------------------------------------
AC_ARG_WITH([gmp],
[AC_HELP_STRING([--with-gmp],
[Enable GMP backend])],
[GMP_ENABLED=YES],
[GMP_ENABLED=NO])
AC_ARG_WITH([gmp-includes],
[AC_HELP_STRING([--with-gmp-includes],
[directory containing gmp.h])],
......@@ -39,74 +45,80 @@ AC_ARG_WITH([intree-gmp],
[GMP_FORCE_INTREE=YES],
[GMP_FORCE_INTREE=NO])
if test "$GMP_ENABLED" = "YES"
then
dnl--------------------------------------------------------------------
dnl * Detect gmp
dnl--------------------------------------------------------------------
HaveLibGmp=NO
GMP_LIBS=
HaveFrameworkGMP=NO
GMP_FRAMEWORK=
HaveSecurePowm=0
if test "$GMP_FORCE_INTREE" != "YES"
then
if test "$GMP_PREFER_FRAMEWORK" = "YES"
then
LOOK_FOR_GMP_FRAMEWORK
LOOK_FOR_GMP_LIB
else
LOOK_FOR_GMP_LIB
LOOK_FOR_GMP_FRAMEWORK
fi
fi
AC_MSG_CHECKING([whether to use in-tree GMP])
if test "$HaveFrameworkGMP" = "YES" || test "$HaveLibGmp" = "YES"
then
AC_MSG_RESULT([no])
UseIntreeGmp=0
AC_CHECK_HEADER([gmp.h], , [AC_MSG_ERROR([Cannot find gmp.h])])
AC_MSG_CHECKING([GMP version])
AC_COMPUTE_INT(GhcGmpVerMj, __GNU_MP_VERSION, [#include <gmp.h>],
AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION]))
AC_COMPUTE_INT(GhcGmpVerMi, __GNU_MP_VERSION_MINOR, [#include <gmp.h>],
AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION_MINOR]))
AC_COMPUTE_INT(GhcGmpVerPl, __GNU_MP_VERSION_PATCHLEVEL, [#include <gmp.h>],
AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION_PATCHLEVEL]))
AC_MSG_RESULT([$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl])
else
AC_MSG_RESULT([yes])
UseIntreeGmp=1
HaveSecurePowm=1
AC_MSG_CHECKING([GMP version])
GhcGmpVerMj=5
GhcGmpVerMi=0
GhcGmpVerPl=4
AC_MSG_RESULT([$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl])
fi
HaveLibGmp=NO
GMP_LIBS=
HaveFrameworkGMP=NO
GMP_FRAMEWORK=
HaveSecurePowm=0
if test "$GMP_FORCE_INTREE" != "YES"
then
if test "$GMP_PREFER_FRAMEWORK" = "YES"
then
LOOK_FOR_GMP_FRAMEWORK
LOOK_FOR_GMP_LIB
else
LOOK_FOR_GMP_LIB
LOOK_FOR_GMP_FRAMEWORK
fi
fi
AC_MSG_CHECKING([whether to use in-tree GMP])
if test "$HaveFrameworkGMP" = "YES" || test "$HaveLibGmp" = "YES"
then
AC_MSG_RESULT([no])
UseIntreeGmp=0
AC_CHECK_HEADER([gmp.h], , [AC_MSG_ERROR([Cannot find gmp.h])])
AC_MSG_CHECKING([GMP version])
AC_COMPUTE_INT(GhcGmpVerMj, __GNU_MP_VERSION, [#include <gmp.h>],
AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION]))
AC_COMPUTE_INT(GhcGmpVerMi, __GNU_MP_VERSION_MINOR, [#include <gmp.h>],
AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION_MINOR]))
AC_COMPUTE_INT(GhcGmpVerPl, __GNU_MP_VERSION_PATCHLEVEL, [#include <gmp.h>],
AC_MSG_ERROR([Unable to get value of __GNU_MP_VERSION_PATCHLEVEL]))
AC_MSG_RESULT([$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl])
else
AC_MSG_RESULT([yes])
UseIntreeGmp=1
HaveSecurePowm=1
AC_MSG_CHECKING([GMP version])
GhcGmpVerMj=6
GhcGmpVerMi=1
GhcGmpVerPl=2
AC_MSG_RESULT([$GhcGmpVerMj.$GhcGmpVerMi.$GhcGmpVerPl])
fi
dnl--------------------------------------------------------------------
dnl * Make sure we got some form of gmp
dnl--------------------------------------------------------------------
AC_SUBST(GMP_INCLUDE_DIRS)
AC_SUBST(GMP_LIBS)
AC_SUBST(GMP_LIB_DIRS)
AC_SUBST(GMP_FRAMEWORK)
AC_SUBST(HaveLibGmp)
AC_SUBST(HaveFrameworkGMP)
AC_SUBST(HaveSecurePowm)
AC_SUBST(UseIntreeGmp)
AC_SUBST(GhcGmpVerMj)
AC_SUBST(GhcGmpVerMi)
AC_SUBST(GhcGmpVerPl)
AC_CONFIG_FILES([integer-gmp.buildinfo config.mk include/HsIntegerGmp.h])
AC_SUBST(GMP_INCLUDE_DIRS)
AC_SUBST(GMP_LIBS)
AC_SUBST(GMP_LIB_DIRS)
AC_SUBST(GMP_FRAMEWORK)
AC_SUBST(HaveLibGmp)
AC_SUBST(HaveFrameworkGMP)
AC_SUBST(HaveSecurePowm)
AC_SUBST(UseIntreeGmp)
AC_SUBST(GhcGmpVerMj)
AC_SUBST(GhcGmpVerMi)
AC_SUBST(GhcGmpVerPl)
AC_CONFIG_FILES([ghc-bignum.buildinfo include/HsIntegerGmp.h])
fi
AC_CONFIG_FILES([config.mk])
dnl--------------------------------------------------------------------
dnl * Generate output files
......
cabal-version: 2.0
name: ghc-bignum
version: 1.0
synopsis: GHC BigNum library
license: BSD3
license-file: LICENSE
author: Sylvain Henry
maintainer: libraries@haskell.org
bug-reports: https://gitlab.haskell.org/ghc/ghc/issues/new
category: Numeric, Algebra, GHC
build-type: Configure
description:
This package provides the low-level implementation of the standard
'BigNat', 'Natural' and 'Integer' types.
extra-source-files:
aclocal.m4
cbits/gmp_wrappers.c
changelog.md
config.guess
config.sub
configure
configure.ac
config.mk.in
install-sh
ghc-bignum.buildinfo.in
source-repository head
type: git
location: https://gitlab.haskell.org/ghc/ghc.git
subdir: libraries/ghc-bignum
Flag Native
Description: Enable native backend
Manual: True
Default: False
Flag FFI
Description: Enable FFI backend
Manual: True
Default: False
Flag GMP
Description: Enable GMP backend
Manual: True
Default: False
Flag Check
Description: Validate results of the enabled backend against native backend.
Manual: True
Default: False
library
-- check that at least one flag is set
if !flag(native) && !flag(gmp) && !flag(ffi)
buildable: False
-- check that at most one flag is set
if flag(native) && (flag(gmp) || flag(ffi))
buildable: False
if flag(gmp) && flag(ffi)
buildable: False
default-language: Haskell2010
other-extensions:
BangPatterns
CApiFFI
CPP
DeriveDataTypeable
ExplicitForAll
GHCForeignImportPrim
MagicHash
NegativeLiterals
NoImplicitPrelude
StandaloneDeriving
UnboxedTuples
UnliftedFFITypes
ForeignFunctionInterface
build-depends:
ghc-prim >= 0.5.1.0 && < 0.7
hs-source-dirs: src/
include-dirs: include/
ghc-options: -Wall
cc-options: -std=c99 -Wall
-- GHC has wired-in IDs from the ghc-bignum package. Hence the unit-id
-- of the package should not contain the version: i.e. it must be
-- "ghc-bignum" and not "ghc-bignum-1.0".
ghc-options: -this-unit-id ghc-bignum
include-dirs: include
if flag(gmp)
cpp-options: -DBIGNUM_GMP
other-modules:
GHC.Num.BigNat.GMP
c-sources:
cbits/gmp_wrappers.c
if flag(ffi)
cpp-options: -DBIGNUM_FFI
other-modules:
GHC.Num.BigNat.FFI
if flag(native)
cpp-options: -DBIGNUM_NATIVE
if flag(check)
cpp-options: -DBIGNUM_CHECK
other-modules:
GHC.Num.BigNat.Check
exposed-modules:
GHC.Num.Primitives
GHC.Num.WordArray
GHC.Num.BigNat
GHC.Num.BigNat.Native
GHC.Num.Natural
GHC.Num.Integer
......@@ -16,8 +16,8 @@
# which causes problems for Debian.
ifneq "$(BINDIST)" "YES"
GMP_TARBALL := $(wildcard libraries/integer-gmp/gmp/gmp-tarballs/gmp*.tar.bz2)
GMP_DIR := $(patsubst libraries/integer-gmp/gmp/gmp-tarballs/%-nodoc.tar.bz2,%,$(GMP_TARBALL))
GMP_TARBALL := $(wildcard libraries/ghc-bignum/gmp/gmp-tarballs/gmp*.tar.bz2)
GMP_DIR := $(patsubst libraries/ghc-bignum/gmp/gmp-tarballs/%-nodoc.tar.bz2,%,$(GMP_TARBALL))
ifeq "$(GMP_TARBALL)" ""
$(error "GMP tarball is missing; you may need to run 'git submodule update --init'.")
......@@ -26,28 +26,28 @@ endif
ifneq "$(NO_CLEAN_GMP)" "YES"
$(eval $(call clean-target,gmp,,\
libraries/integer-gmp/include/ghc-gmp.h \
libraries/integer-gmp/gmp/libgmp.a \
libraries/integer-gmp/gmp/gmp.h \
libraries/integer-gmp/gmp/gmpbuild \
libraries/integer-gmp/gmp/$(GMP_DIR)))
libraries/ghc-bignum/include/ghc-gmp.h \
libraries/ghc-bignum/gmp/libgmp.a \
libraries/ghc-bignum/gmp/gmp.h \
libraries/ghc-bignum/gmp/gmpbuild \
libraries/ghc-bignum/gmp/$(GMP_DIR)))
clean : clean_gmp
.PHONY: clean_gmp
clean_gmp:
$(call removeTrees,libraries/integer-gmp/gmp/objs)
$(call removeTrees,libraries/integer-gmp/gmp/gmpbuild)
$(call removeTrees,libraries/ghc-bignum/gmp/objs)
$(call removeTrees,libraries/ghc-bignum/gmp/gmpbuild)
endif
ifeq "$(GMP_PREFER_FRAMEWORK)" "YES"
libraries/integer-gmp_CONFIGURE_OPTS += --with-gmp-framework-preferred
libraries/ghc-bignum_CONFIGURE_OPTS += --with-gmp-framework-preferred
endif
ifneq "$(CLEANING)" "YES"
# Hack. The file config.mk doesn't exist yet after running ./configure in
# the toplevel (ghc) directory. To let some toplevel make commands such as
# sdist go through, right after ./configure, don't consider this an error.
-include libraries/integer-gmp/dist-install/build/config.mk
-include libraries/ghc-bignum/dist-install/build/config.mk
endif
gmp_CC_OPTS += $(addprefix -I,$(GMP_INCLUDE_DIRS))
......@@ -67,7 +67,7 @@ endif
# In a bindist, we don't want to know whether /this/ machine has gmp,
# but whether the machine the bindist was built on had gmp.
ifeq "$(BINDIST)" "YES"
ifeq "$(wildcard libraries/integer-gmp/gmp/libgmp.a)" ""
ifeq "$(wildcard libraries/ghc-bignum/gmp/libgmp.a)" ""
HaveLibGmp = YES
HaveFrameworkGMP = YES
else
......@@ -89,21 +89,21 @@ libraries/integer-gmp/cbits/wrappers.c: libraries/integer-gmp/include/ghc-gmp.h
ifeq "$(UseIntreeGmp)" "YES"
# Copy header from in-tree build (gmp.h => ghc-gmp.h)
libraries/integer-gmp/include/ghc-gmp.h: libraries/integer-gmp/gmp/gmp.h
libraries/ghc-bignum/include/ghc-gmp.h: libraries/ghc-bignum/gmp/gmp.h
$(CP) $< $@
# Link in-tree GMP objects
libraries/integer-gmp_dist-install_EXTRA_OBJS += libraries/integer-gmp/gmp/objs/*.o
libraries/ghc-bignum_dist-install_EXTRA_OBJS += libraries/ghc-bignum/gmp/objs/*.o
else
# Copy header from source tree
libraries/integer-gmp/include/ghc-gmp.h: libraries/integer-gmp/gmp/ghc-gmp.h
libraries/ghc-bignum/include/ghc-gmp.h: libraries/ghc-bignum/gmp/ghc-gmp.h
$(CP) $< $@
endif
libraries/integer-gmp_dist-install_EXTRA_CC_OPTS += $(gmp_CC_OPTS)
libraries/ghc-bignum_dist-install_EXTRA_CC_OPTS += $(gmp_CC_OPTS)
ifneq "$(CLEANING)" "YES"
# When running `make clean` before `./configure`, CC_STAGE1 is undefined.
......@@ -115,25 +115,25 @@ else
CCX = $(CC_STAGE1)
endif
libraries/integer-gmp/gmp/libgmp.a libraries/integer-gmp/gmp/gmp.h:
$(RM) -rf libraries/integer-gmp/gmp/$(GMP_DIR) libraries/integer-gmp/gmp/gmpbuild libraries/integer-gmp/gmp/objs
cat $(GMP_TARBALL) | $(BZIP2_CMD) -d | { cd libraries/integer-gmp/gmp && $(TAR_CMD) -xf - ; }
mv libraries/integer-gmp/gmp/$(GMP_DIR) libraries/integer-gmp/gmp/gmpbuild
cd libraries/integer-gmp/gmp && $(PATCH_CMD) -p0 < gmpsrc.patch
chmod +x libraries/integer-gmp/gmp/ln
libraries/ghc-bignum/gmp/libgmp.a libraries/ghc-bignum/gmp/gmp.h:
$(RM) -rf libraries/ghc-bignum/gmp/$(GMP_DIR) libraries/ghc-bignum/gmp/gmpbuild libraries/ghc-bignum/gmp/objs
cat $(GMP_TARBALL) | $(BZIP2_CMD) -d | { cd libraries/ghc-bignum/gmp && $(TAR_CMD) -xf - ; }
mv libraries/ghc-bignum/gmp/$(GMP_DIR) libraries/ghc-bignum/gmp/gmpbuild
cd libraries/ghc-bignum/gmp && $(PATCH_CMD) -p0 < gmpsrc.patch
chmod +x libraries/ghc-bignum/gmp/ln
# Note: We must pass `TARGETPLATFORM` to the `--host` argument of GMP's
# `./configure`, not `HOSTPLATFORM`: the 'host' on which GMP will
# run is the 'target' platform of the compiler we're building.
cd libraries/integer-gmp/gmp/gmpbuild; \
cd libraries/ghc-bignum/gmp/gmpbuild; \
CC=$(CCX) CXX=$(CCX) NM=$(NM) AR=$(AR_STAGE1) ./configure \
--enable-shared=no --with-pic=yes \
--host=$(TARGETPLATFORM) --build=$(BUILDPLATFORM)
$(MAKE) -C libraries/integer-gmp/gmp/gmpbuild MAKEFLAGS=
$(CP) libraries/integer-gmp/gmp/gmpbuild/gmp.h libraries/integer-gmp/gmp/
$(CP) libraries/integer-gmp/gmp/gmpbuild/.libs/libgmp.a libraries/integer-gmp/gmp/
$(MKDIRHIER) libraries/integer-gmp/gmp/objs
cd libraries/integer-gmp/gmp/objs && $(AR_STAGE1) x ../libgmp.a
$(RANLIB_CMD) libraries/integer-gmp/gmp/libgmp.a
$(MAKE) -C libraries/ghc-bignum/gmp/gmpbuild MAKEFLAGS=
$(CP) libraries/ghc-bignum/gmp/gmpbuild/gmp.h libraries/ghc-bignum/gmp/
$(CP) libraries/ghc-bignum/gmp/gmpbuild/.libs/libgmp.a libraries/ghc-bignum/gmp/
$(MKDIRHIER) libraries/ghc-bignum/gmp/objs
cd libraries/ghc-bignum/gmp/objs && $(AR_STAGE1) x ../libgmp.a
$(RANLIB_CMD) libraries/ghc-bignum/gmp/libgmp.a
endif # CLEANING
File moved
#pragma once
/* Whether GMP is embedded into integer-gmp */
/* Whether GMP is embedded into ghc-bignum */
#define GHC_GMP_INTREE @UseIntreeGmp@
/* The following values denote the GMP version used during GHC build-time */
......
#include "MachDeps.h"
#if WORD_SIZE_IN_BITS == 64
# define WORD_SIZE_IN_BYTES 8
# define WORD_SIZE_BYTES_SHIFT 3
# define WORD_SIZE_BYTES_MASK 0b111
# define WORD_SIZE_BITS_SHIFT 6
# define WORD_SIZE_BITS_MASK 0b111111
# define WORD_MAXBOUND 0xffffffffffffffff
# define INT_MINBOUND -0x8000000000000000
# define INT_MAXBOUND 0x7fffffffffffffff
# define ABS_INT_MINBOUND 0x8000000000000000
# define SQRT_INT_MAXBOUND 0xb504f333
#elif WORD_SIZE_IN_BITS == 32
# define WORD_SIZE_IN_BYTES 4
# define WORD_SIZE_BYTES_SHIFT 2
# define WORD_SIZE_BYTES_MASK 0b11
# define WORD_SIZE_BITS_SHIFT 5
# define WORD_SIZE_BITS_MASK 0b11111
# define WORD_MAXBOUND 0xffffffff
# define INT_MINBOUND -0x80000000
# define INT_MAXBOUND 0x7fffffff
# define ABS_INT_MINBOUND 0x80000000
# define SQRT_INT_MAXBOUND 0xb504
#else
# error unsupported WORD_SIZE_IN_BITS config
#endif
This diff is collapsed.
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE UnboxedTuples #-}
module GHC.Num.BigNat where