From 02107450d0c68a372f720974c92fe16acf3961f9 Mon Sep 17 00:00:00 2001 From: Odysseas Gabrielides Date: Wed, 9 Oct 2024 17:25:18 +0300 Subject: [PATCH] Squashed 'src/dashbls/' changes from 795660db76..4e070243ae 4e070243ae chore: bump version to 1.3.3 (#99) d93956254e ci: disable Go bindings CI for macos for now (#98) ae40c5c86d Merge pull request #97 from PastaPastaPasta/refac/pybind-bump-2.13.6 e835ece935 refactor: bump pybind version to 2.13.6 eda5d6a402 chore: change of gmp source (#95) 61f95aa80e chore: cleanup 6.2.1 left overs (#96) adbd094409 Merge pull request #92 from kwvg/darwin_gmp 062ee6726b Merge pull request #90 from UdjinM6/fix_aarch_arch 3538d8b033 fix: aarch64 is not supported, should set ARCH to RELIC_NONE e27a62f4a2 revert: disable gmp if targeting darwin on aarch64 when on 'auto' bb2fe6ee55 build: enforce minimum version of libgmp based on arch and platform 9832b7a132 build: replace deprecated macros `AC_PROG_CC_C99` and `AM_PROG_CC_C_O` b2428718b9 Merge pull request #91 from UdjinM6/fix_macos_test_build 3ffa7fa2b6 chore: bump version to 1.3.2 (#94) 0f4efc9327 Merge pull request #88 from HashEngineering/feat/support-android a181889489 fix: rust bindings build for macos (#89) 738d187359 fix: detect gmp via brew earlier ce4d6a47b6 fix: install libtool 4fa46ccaff fix: use macos-latest for test build 69bdc1aac7 Merge pull request #85 from kwvg/debug 39791d4e31 build: print build options after configure 73106a0121 build: use `-mbranch-protection=bti` on supporting `aarch64` compilers 6a3c28f6ca build: use stricter `-Werror` when testing compile flags 7a1b227637 build: rename {`NO`}`WARN_CFLAGS` to {`NO`}`WARN_FLAGS`, use with C{++} 28bea63838 build: set {`NO`}`WARN_CFLAGS` flags if not overridden and uniformly 32c2f0f5f8 trivial: rename `CORE_CXXFLAGS` to `CORE_FLAGS`, use with C{++} b630c2c323 build: append `HARDENED_FLAGS` to `AM_CFLAGS` e6008148e4 trivial: rename `HARDENED_CXXFLAGS` to `HARDENED_FLAGS` af0e3daef5 build: subsume `PI{C,E}_FLAGS` into `HARDENED_CXXFLAGS` 9ff8618a1b build: expand `--disable-optimizations` to include `-O0` and `-fwrapv` 3036b83181 build: expand `--enable-debug` to include `-O0`, `-ftrapv` and dbg info c90d43d43b build: add check to see if `CFLAGS` has been overridden 2d77f7ae49 build: remove vestigial `LIBTOOL_{CXX,CPP,LD}FLAGS`, `HARDENED_CPPFLAGS` 883a098868 build: autodetect i?86 and arm as 32-bit deb3269820 build: don't specify exact `{CPU_}ARCH` if optimizations are disabled 720d49a44b trivial: fix indentation for `want_backend` check f9328320af build: use `easy` backend if optimizations are disabled unless specified 3687cd59e0 build: define new flag `--enable-optimizations` f82bfee5dd build: ensure help string format matches Autotool defaults d68920063e build: define arguments as `--enable-[term]` instead of `--disable-[term]` 7f41e7dd16 fix: support android 1c2fc79c19 feat(rust): allow to move G1 and G2 elements between threads (#87) 3540b8bbed feat: debug with data hex (#86) git-subtree-dir: src/dashbls git-subtree-split: 4e070243aed142bc458472f8807ab77527dd879a --- .github/workflows/build-binds.yml | 2 + .github/workflows/build-test.yaml | 4 +- Makefile.am | 7 +- Makefile.relic.include | 2 +- apple.rust.deps.sh | 47 +- apple.rust.sh | 458 ---- apple.rust.single.sh | 404 --- configure.ac | 368 ++- contrib/gmp-patch-6.2.1/compat.c | 65 - contrib/gmp-patch-6.2.1/longlong.h | 2355 ----------------- python-bindings/CMakeLists.txt | 2 +- rust-bindings/bls-dash-sys/build.rs | 89 +- rust-bindings/bls-signatures/Cargo.toml | 1 + rust-bindings/bls-signatures/src/elements.rs | 47 +- .../bls-signatures/src/legacy/elements.rs | 8 + rust-bindings/bls-signatures/src/lib.rs | 22 + .../bls-signatures/src/private_key.rs | 9 +- 17 files changed, 432 insertions(+), 3458 deletions(-) delete mode 100755 apple.rust.sh delete mode 100755 apple.rust.single.sh delete mode 100644 contrib/gmp-patch-6.2.1/compat.c delete mode 100644 contrib/gmp-patch-6.2.1/longlong.h diff --git a/.github/workflows/build-binds.yml b/.github/workflows/build-binds.yml index 92e0f04ec2..f57acbd7e2 100644 --- a/.github/workflows/build-binds.yml +++ b/.github/workflows/build-binds.yml @@ -77,6 +77,8 @@ jobs: cmake --build . -- -j 6 - name: Build Go bindings + # TODO: macos build is broken. Whoever needs this - please fix it and remove `if` below. + if: startsWith(matrix.os, 'ubuntu') run: | cd go-bindings make diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml index 67ea03f8a4..e023515ee2 100644 --- a/.github/workflows/build-test.yaml +++ b/.github/workflows/build-test.yaml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - os: [ macos-11, ubuntu-20.04 ] + os: [ macos-latest, ubuntu-20.04 ] builder: [ cmake, autotools ] compiler: - cc: gcc @@ -47,7 +47,7 @@ jobs: run: | ls -l export MACOSX_DEPLOYMENT_TARGET=10.14 - brew install autoconf automake gmp pkg-config + brew install autoconf automake gmp libtool pkg-config - name: Build library using CMake if: startsWith(matrix.builder, 'cmake') diff --git a/Makefile.am b/Makefile.am index 9ce6ff4f6c..1c1e5d19d5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,9 +9,10 @@ print-%: FORCE ACLOCAL_AMFLAGS = -I build-aux/m4 .PHONY: deploy FORCE -AM_LDFLAGS = $(LIBTOOL_LDFLAGS) $(HARDENED_LDFLAGS) $(CORE_LDFLAGS) $(GMP_LDFLAGS) -AM_CXXFLAGS = $(LIBTOOL_CXXFLAGS) $(HARDENED_CXXFLAGS) $(CORE_CXXFLAGS) $(PIC_FLAGS) $(PIE_FLAGS) -AM_CPPFLAGS = $(LIBTOOL_CPPFLAGS) $(HARDENED_CPPFLAGS) $(CORE_CPPFLAGS) $(PIC_FLAGS) $(GMP_CPPFLAGS) +AM_LDFLAGS = $(HARDENED_LDFLAGS) $(CORE_LDFLAGS) $(GMP_LDFLAGS) +AM_CFLAGS = $(DEBUG_FLAGS) $(HARDENED_FLAGS) $(CORE_FLAGS) $(WARN_FLAGS) $(NOWARN_FLAGS) +AM_CPPFLAGS = $(CORE_CPPFLAGS) $(GMP_CPPFLAGS) +AM_CXXFLAGS = $(DEBUG_FLAGS) $(HARDENED_FLAGS) $(CORE_FLAGS) $(WARN_FLAGS) $(NOWARN_FLAGS) PTHREAD_FLAGS = $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) EXTRA_LIBRARIES = diff --git a/Makefile.relic.include b/Makefile.relic.include index 725e8ca4f2..92bd7c7e8f 100644 --- a/Makefile.relic.include +++ b/Makefile.relic.include @@ -464,7 +464,7 @@ librelic_la_SOURCES = \ librelic_la_CPPFLAGS = $(AM_CPPFLAGS) $(RELIC_CPPFLAGS) $(RELIC_INCLUDES) librelic_la_CXXFLAGS = $(AM_CXXFLAGS) -librelic_la_CFLAGS = $(AM_CFLAGS) $(WARN_CFLAGS) $(NOWARN_CFLAGS) +librelic_la_CFLAGS = $(AM_CFLAGS) librelic_la_LDFLAGS = $(AM_LDFLAGS) noinst_LTLIBRARIES += $(LIBRELIC) diff --git a/apple.rust.deps.sh b/apple.rust.deps.sh index 7d3b8de22f..b2ebc41a4f 100755 --- a/apple.rust.deps.sh +++ b/apple.rust.deps.sh @@ -1,5 +1,6 @@ #!/bin/sh set -x +set -e # "x86_64-apple-ios" # "aarch64-apple-ios" # "aarch64-apple-ios-sim" @@ -51,22 +52,20 @@ version_min_flag() { prepare() { download_gmp() { - GMP_VERSION="6.2.1" + GMP_VERSION="6.3.0" CURRENT_DIR=$(pwd) echo "$CURRENT_DIR" # shellcheck disable=SC2039,SC2164 pushd ${BUILD} mkdir -p "contrib" if [ ! -s "contrib/gmp-${GMP_VERSION}.tar.bz2" ]; then - curl -L -o "contrib/gmp-${GMP_VERSION}.tar.bz2" https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.bz2 + curl -L -o "contrib/gmp-${GMP_VERSION}.tar.bz2" https://ftp.gnu.org/gnu/gmp/gmp-${GMP_VERSION}.tar.bz2 fi rm -rf "contrib/gmp" # shellcheck disable=SC2039,SC2164 pushd contrib tar xfj "gmp-${GMP_VERSION}.tar.bz2" mv gmp-${GMP_VERSION} gmp - rm gmp/compat.c && cp ../../contrib/gmp-patch-6.2.1/compat.c gmp/compat.c - rm gmp/longlong.h && cp ../../contrib/gmp-patch-6.2.1/longlong.h gmp/longlong.h # shellcheck disable=SC2039,SC2164 popd #contrib # shellcheck disable=SC2039,SC2164 @@ -88,10 +87,10 @@ prepare() { download_relic() { CURRENT_DIR=$(pwd) echo "$CURRENT_DIR" - mkdir -p "${CURRENT_DIR}/${BUILD}/contrib" - if [ ! -s "${CURRENT_DIR}/${BUILD}/contrib/relic" ]; then + mkdir -p "${CURRENT_DIR}/${BUILD}/depends" + if [ ! -s "${CURRENT_DIR}/${BUILD}/depends/relic" ]; then # shellcheck disable=SC2039,SC2164 - pushd "${CURRENT_DIR}/${BUILD}/contrib" + pushd "${CURRENT_DIR}/${BUILD}/depends" git clone --depth 1 --branch "feat/ios-support" https://github.com/pankcuf/relic # shellcheck disable=SC2039,SC2164 pushd relic @@ -100,7 +99,7 @@ prepare() { # shellcheck disable=SC2039,SC2164 popd #relic # shellcheck disable=SC2039,SC2164 - popd #contrib + popd #depends fi } rm -rf ${BUILD} @@ -115,7 +114,7 @@ build_gmp_arch() { ARCH=$2 PFX=${PLATFORM}-${ARCH} # why this works with this host only? - HOST=arm-apple-darwin + HOST=aarch64-apple-darwin # shellcheck disable=SC2039,SC2164 pushd ${BUILD} SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) @@ -143,7 +142,7 @@ CC="$CLANG" CFLAGS="$CFLAGS" CPPFLAGS="$CFLAGS" LDFLAGS="$CFLAGS" \ --host=${HOST} --prefix="${CURRENT_DIR}/gmplib-${PFX}" \ --disable-shared --enable-static --disable-assembly -v EOF - + chmod a+x "$CONFIGURESCRIPT" sh "$CONFIGURESCRIPT" rm "$CONFIGURESCRIPT" @@ -154,6 +153,8 @@ EOF make -j "$LOGICALCPU_MAX" &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-build.log # shellcheck disable=SC2039 make install &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-install.log + #make check + #exit 1 # shellcheck disable=SC2039,SC2164 popd # gmp # shellcheck disable=SC2039,SC2164 @@ -258,15 +259,15 @@ build_relic_arch() { EXTRA_ARGS+=" -DARCH=X86" elif [[ $ARCH = "x86_64" ]]; then EXTRA_ARGS+=" -DARCH=X64" - else - EXTRA_ARGS+=" -DARCH=ARM" - if [[ $ARCH = "armv7s" ]]; then - EXTRA_ARGS+=" -DIOS_ARCH=armv7s" - elif [[ $ARCH = "armv7k" ]]; then - EXTRA_ARGS+=" -DIOS_ARCH=armv7k" - elif [[ $ARCH = "arm64_32" ]]; then - EXTRA_ARGS+=" -DIOS_ARCH=arm64_32" - fi + elif [[ $ARCH = "arm64" ]]; then + # Relic doesn't support aarch64 yet, "ARCH=ARM" is for ARM 32-bit architecture only + EXTRA_ARGS+=" -DIOS_ARCH=arm64 -DARCH=" + elif [[ $ARCH = "armv7s" ]]; then + EXTRA_ARGS+=" -DIOS_ARCH=armv7s -DARCH=ARM" + elif [[ $ARCH = "armv7k" ]]; then + EXTRA_ARGS+=" -DIOS_ARCH=armv7k -DARCH=ARM" + elif [[ $ARCH = "arm64_32" ]]; then + EXTRA_ARGS+=" -DIOS_ARCH=arm64_32 -DARCH=ARM" fi CURRENT_DIR=$(pwd) @@ -281,7 +282,7 @@ build_relic_arch() { # shellcheck disable=SC2039,SC2164 popd # "$BUILDDIR" # shellcheck disable=SC2039,SC2164 - popd # contrib/relic + popd # depends/relic } build_bls_arch() { @@ -311,7 +312,7 @@ build_bls_arch() { clang -I"../contrib/relic/include" \ -I"../../depends/relic/include" \ -I"../../include/dashbls" \ - -I"../relic-${PFX}/_deps/relic-build/include" \ + -I"../relic-${PFX}/depends/relic/include" \ -I"../../src/" \ -I"../gmplib-${PFX}/include" \ -x c++ -std=c++14 -stdlib=libc++ -fembed-bitcode -arch "${ARCH}" -isysroot "${SDK}" "${EXTRA_ARGS}" \ @@ -360,8 +361,8 @@ build_target() { rm -rf "build/artefacts/${BUILD_IN}" mkdir -p "build/artefacts/${BUILD_IN}" cp "build/gmplib-${PFX}/lib/libgmp.a" "build/artefacts/${BUILD_IN}" - cp "build/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" "build/artefacts/${BUILD_IN}" - cp "build/relic-${PFX}/_deps/sodium-build/libsodium.a" "build/artefacts/${BUILD_IN}" + cp "build/relic-${PFX}/depends/relic/lib/librelic_s.a" "build/artefacts/${BUILD_IN}" +# cp "build/relic-${PFX}/depends/sodium/libsodium.a" "build/artefacts/${BUILD_IN}" cp "build/bls-${PFX}/libbls.a" "build/artefacts/${BUILD_IN}" # cp -rf build/bls-"${PFX}"/*.o build/artefacts/"${BUILD_IN}"/include # cp -rf src/*.hpp build/artefacts/"${BUILD_IN}"/include diff --git a/apple.rust.sh b/apple.rust.sh deleted file mode 100755 index e105c3ce6c..0000000000 --- a/apple.rust.sh +++ /dev/null @@ -1,458 +0,0 @@ -#!/bin/sh -set -x - -git submodule update --init - -MIN_IOS="13.0" -MIN_WATCHOS="5.0" -MIN_TVOS=$MIN_IOS -MIN_MACOS="10.15" - -IPHONEOS=iphoneos -IPHONESIMULATOR=iphonesimulator -WATCHOS=watchos -WATCHSIMULATOR=watchsimulator -TVOS=appletvos -TVSIMULATOR=appletvsimulator -MACOS=macosx - -LOGICALCPU_MAX=$(sysctl -n hw.logicalcpu_max) -BUILD=build - -version_min_flag() { - PLATFORM=$1 - FLAG="" - # shellcheck disable=SC2039 - # shellcheck disable=SC2053 - if [[ $PLATFORM = $IPHONEOS ]]; then - FLAG="-miphoneos-version-min=${MIN_IOS}" - elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then - FLAG="-mios-simulator-version-min=${MIN_IOS}" - elif [[ $PLATFORM = $WATCHOS ]]; then - FLAG="-mwatchos-version-min=${MIN_WATCHOS}" - elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then - FLAG="-mwatchos-simulator-version-min=${MIN_WATCHOS}" - elif [[ $PLATFORM = $TVOS ]]; then - FLAG="-mtvos-version-min=${MIN_TVOS}" - elif [[ $PLATFORM = $TVSIMULATOR ]]; then - FLAG="-mtvos-simulator-version-min=${MIN_TVOS}" - elif [[ $PLATFORM = $MACOS ]]; then - FLAG="-mmacosx-version-min=${MIN_MACOS}" - fi - echo $FLAG -} - - -prepare() { - download_gmp() { - GMP_VERSION="6.2.1" - CURRENT_DIR=$(pwd) - echo "$CURRENT_DIR" - # shellcheck disable=SC2039,SC2164 - pushd ${BUILD} - mkdir -p "contrib" - if [ ! -s "contrib/gmp-${GMP_VERSION}.tar.bz2" ]; then - curl -L -o "contrib/gmp-${GMP_VERSION}.tar.bz2" https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.bz2 - fi - rm -rf "contrib/gmp" - # shellcheck disable=SC2039,SC2164 - pushd contrib - tar xfj "gmp-${GMP_VERSION}.tar.bz2" - mv gmp-${GMP_VERSION} gmp - rm gmp/compat.c && cp ../../contrib/gmp-patch-6.2.1/compat.c gmp/compat.c - rm gmp/longlong.h && cp ../../contrib/gmp-patch-6.2.1/longlong.h gmp/longlong.h - # shellcheck disable=SC2039,SC2164 - popd #contrib - # shellcheck disable=SC2039,SC2164 - popd #build - } - - download_cmake_toolchain() { - if [ ! -s "${BUILD}/ios.toolchain.cmake" ]; then - SHA256_HASH="d02857ff6bd64f1d7109ca59c3e4f3b2f89d0663c412146e6977c679801b3243" - curl -o "${BUILD}/ios.toolchain.cmake" https://raw.githubusercontent.com/leetal/ios-cmake/c55677a4445b138c9ef2650d3c21f22cc78c2357/ios.toolchain.cmake - DOWNLOADED_HASH=$(shasum -a 256 ${BUILD}/ios.toolchain.cmake | cut -f 1 -d " ") - if [ $SHA256_HASH != "$DOWNLOADED_HASH" ]; then - echo "Error: sha256 checksum of ios.toolchain.cmake mismatch" >&2 - exit 1 - fi - fi - } - - download_relic() { - CURRENT_DIR=$(pwd) - echo "$CURRENT_DIR" - mkdir -p "${CURRENT_DIR}/${BUILD}/contrib" - if [ ! -s "${CURRENT_DIR}/${BUILD}/contrib/relic" ]; then - # shellcheck disable=SC2039,SC2164 - pushd "${CURRENT_DIR}/${BUILD}/contrib" - git clone --depth 1 --branch "feat/ios-support" https://github.com/pankcuf/relic - # shellcheck disable=SC2039,SC2164 - pushd relic - git fetch --depth 1 origin 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae - git checkout 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae - # shellcheck disable=SC2039,SC2164 - popd #relic - # shellcheck disable=SC2039,SC2164 - popd #contrib - fi - } - rm -rf ${BUILD} - mkdir -p ${BUILD} - download_relic - download_gmp - download_cmake_toolchain - mkdir -p ${BUILD}/artefacts/include -} - -build_gmp_arch() { - PLATFORM=$1 - ARCH=$2 - PFX=${PLATFORM}-${ARCH} - # why this works with this host only? - HOST=arm-apple-darwin - # shellcheck disable=SC2039,SC2164 - pushd ${BUILD} - SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) - PLATFORM_PATH=$(xcrun --sdk "$PLATFORM" --show-sdk-platform-path) - CLANG=$(xcrun --sdk "$PLATFORM" --find clang) - DEVELOPER=$(xcode-select --print-path) - CURRENT_DIR=$(pwd) - export PATH="${PLATFORM_PATH}/Developer/usr/bin:${DEVELOPER}/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin" - mkdir gmplib-"${PLATFORM}"-"${ARCH}" - CFLAGS="-Wno-unused-value -fembed-bitcode -arch ${ARCH} --sysroot=${SDK} $(version_min_flag "$PLATFORM")" - CONFIGURESCRIPT="gmp_configure_script.sh" - # shellcheck disable=SC2039,SC2164 - pushd contrib - # shellcheck disable=SC2039,SC2164 - pushd gmp - make clean || true - make distclean || true - echo "HOST: $HOST" - echo "PREFIX: ${CURRENT_DIR}/gmplib-${PFX}" - - cat >"$CONFIGURESCRIPT" << EOF -#!/bin/sh -./configure \ -CC="$CLANG" CFLAGS="$CFLAGS" CPPFLAGS="$CFLAGS" LDFLAGS="$CFLAGS" \ ---host=${HOST} --prefix="${CURRENT_DIR}/gmplib-${PFX}" \ ---disable-shared --enable-static --disable-assembly -v -EOF - - chmod a+x "$CONFIGURESCRIPT" - sh "$CONFIGURESCRIPT" - rm "$CONFIGURESCRIPT" - - # shellcheck disable=SC2039 - mkdir -p "${CURRENT_DIR}/log" - # shellcheck disable=SC2039 - make -j "$LOGICALCPU_MAX" &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-build.log - # shellcheck disable=SC2039 - make install &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-install.log - # shellcheck disable=SC2039,SC2164 - popd # gmp - # shellcheck disable=SC2039,SC2164 - popd # contrib - # shellcheck disable=SC2039,SC2164 - popd # build -} - -build_relic_arch() { - PLATFORM=$1 - ARCH=$2 - PFX=${PLATFORM}-${ARCH} - - # shellcheck disable=SC2039,SC2164 - pushd ${BUILD} - - SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) - - BUILDDIR=relic-"${PFX}" - TOOLCHAIN=$(pwd)/ios.toolchain.cmake - GMP_PFX=$(pwd)/gmplib-${PFX} - rm -rf "$BUILDDIR" - mkdir "$BUILDDIR" - # shellcheck disable=SC2039,SC2164 - pushd "$BUILDDIR" - - unset CC - # shellcheck disable=SC2155 - export CC=$(xcrun --sdk "${PLATFORM}" --find clang) - - WSIZE=0 - IOS_PLATFORM="" - OPTIMIZATIONFLAGS="" - DEPLOYMENT_TARGET="" - - # shellcheck disable=SC2039 - # shellcheck disable=SC2053 - if [[ $PLATFORM = $IPHONEOS ]]; then - if [[ $ARCH = "arm64" ]] || [[ $ARCH = "arm64e" ]]; then - IOS_PLATFORM=OS64 - DEPLOYMENT_TARGET=$MIN_IOS - WSIZE=64 - OPTIMIZATIONFLAGS=-fomit-frame-pointer - else - IOS_PLATFORM=OS - WSIZE=32 - fi - elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then - if [[ $ARCH = "x86_64" ]]; then - IOS_PLATFORM=SIMULATOR64 - DEPLOYMENT_TARGET=$MIN_IOS - WSIZE=64 - OPTIMIZATIONFLAGS=-fomit-frame-pointer - elif [[ $ARCH = "arm64" ]]; then - IOS_PLATFORM=SIMULATORARM64 - DEPLOYMENT_TARGET=$MIN_IOS - WSIZE=64 - else - IOS_PLATFORM=SIMULATOR - WSIZE=32 - fi - elif [[ $PLATFORM = $WATCHOS ]]; then - IOS_PLATFORM=WATCHOS - DEPLOYMENT_TARGET=$MIN_WATCHOS - WSIZE=32 - elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then - IOS_PLATFORM=SIMULATOR_WATCHOS - DEPLOYMENT_TARGET=$MIN_WATCHOS - WSIZE=32 - elif [[ $PLATFORM = $TVOS ]]; then - IOS_PLATFORM=TVOS - DEPLOYMENT_TARGET=$MIN_TVOS - WSIZE=64 - OPTIMIZATIONFLAGS=-fomit-frame-pointer - elif [[ $PLATFORM = $TVSIMULATOR ]]; then - IOS_PLATFORM=SIMULATOR_TVOS - #TODO - if [[ $ARCH = "arm64" ]] - then - IOS_PLATFORM=OS64 - fi - DEPLOYMENT_TARGET=$MIN_TVOS - WSIZE=64 - OPTIMIZATIONFLAGS=-fomit-frame-pointer - elif [[ $PLATFORM = $MACOS ]]; then - WSIZE=64 - IOS_PLATFORM=MAC - if [[ $ARCH = "arm64" ]] - then - IOS_PLATFORM=MAC_ARM64 - fi - DEPLOYMENT_TARGET=$MIN_MACOS - OPTIMIZATIONFLAGS=-fomit-frame-pointer - fi - - COMPILER_ARGS="$(version_min_flag "$PLATFORM") -Wno-unused-functions" - - EXTRA_ARGS="-DOPSYS=NONE -DPLATFORM=$IOS_PLATFORM -DDEPLOYMENT_TARGET=$DEPLOYMENT_TARGET -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN" - - # shellcheck disable=SC2039 - if [[ $ARCH = "i386" ]]; then - EXTRA_ARGS+=" -DARCH=X86" - elif [[ $ARCH = "x86_64" ]]; then - EXTRA_ARGS+=" -DARCH=X64" - else - EXTRA_ARGS+=" -DARCH=ARM" - if [[ $ARCH = "armv7s" ]]; then - EXTRA_ARGS+=" -DIOS_ARCH=armv7s" - elif [[ $ARCH = "armv7k" ]]; then - EXTRA_ARGS+=" -DIOS_ARCH=armv7k" - elif [[ $ARCH = "arm64_32" ]]; then - EXTRA_ARGS+=" -DIOS_ARCH=arm64_32" - fi - fi - - CURRENT_DIR=$(pwd) - cmake -DCMAKE_PREFIX_PATH:PATH="${GMP_PFX}" -DTESTS=0 -DBENCH=0 -DBUILD_BLS_JS_BINDINGS=0 -DBUILD_BLS_PYTHON_BINDINGS=0 \ - -DBUILD_BLS_BENCHMARKS=0 -DBUILD_BLS_TESTS=0 -DCHECK=off -DARITH=gmp -DTIMER=HPROC -DFP_PRIME=381 -DMULTI=PTHREAD \ - -DFP_QNRES=on -DFP_METHD="INTEG;INTEG;INTEG;MONTY;EXGCD;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" \ - -DCOMP_FLAGS="-pipe -std=c99 -O3 -funroll-loops $OPTIMIZATIONFLAGS -isysroot $SDK -arch $ARCH -fembed-bitcode ${COMPILER_ARGS}" \ - -DWSIZE=$WSIZE -DVERBS=off -DSHLIB=off -DALLOC="AUTO" -DEP_PLAIN=off -DEP_SUPER=off -DPP_EXT="LAZYR" \ - -DWITH="DV;BN;MD;FP;EP;FPX;EPX;PP;PC;CP" -DBN_METHD="COMBA;COMBA;MONTY;SLIDE;STEIN;BASIC" ${EXTRA_ARGS} ../../ - - make -j "$LOGICALCPU_MAX" - # shellcheck disable=SC2039,SC2164 - popd # "$BUILDDIR" - # shellcheck disable=SC2039,SC2164 - popd # contrib/relic -} - -build_bls_arch() { - # shellcheck disable=SC2039 - BLS_FILES=( "bls" "chaincode" "elements" "extendedprivatekey" "extendedpublickey" "legacy" "privatekey" "schemes" "threshold" ) - # shellcheck disable=SC2039 - ALL_BLS_OBJ_FILES=$(printf "%s.o " "${BLS_FILES[@]}") - - PLATFORM=$1 - ARCH=$2 - PFX=${PLATFORM}-${ARCH} - SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) - - BUILDDIR=${BUILD}/bls-"${PFX}" - rm -rf "$BUILDDIR" - mkdir "$BUILDDIR" - # shellcheck disable=SC2039,SC2164 - pushd "$BUILDDIR" - - EXTRA_ARGS="$(version_min_flag "$PLATFORM")" - - CURRENT_DIR=$(pwd) - - # shellcheck disable=SC2039 - for F in "${BLS_FILES[@]}" - do - clang -I"../contrib/relic/include" \ - -I"../relic-${PFX}/_deps/relic-build/include" \ - -I"../../src/" \ - -I"../gmplib-${PFX}/include" \ - -x c++ -std=c++14 -stdlib=libc++ -fembed-bitcode -arch "${ARCH}" -isysroot "${SDK}" "${EXTRA_ARGS}" \ - -c "../../src/${F}.cpp" -o "${F}.o" - done - - # shellcheck disable=SC2086 - xcrun -sdk "$PLATFORM" ar -cvq libbls.a $ALL_BLS_OBJ_FILES - - # shellcheck disable=SC2039,SC2164 - popd # "$BUILDDIR" -} - -build_all_arch() { - PLATFORM=$1 - ARCH=$2 - build_gmp_arch "$PLATFORM" "$ARCH" - build_relic_arch "$PLATFORM" "$ARCH" - build_bls_arch "$PLATFORM" "$ARCH" -} - -build_all() { - BUILD_IN=$1 - TARGET_DIR=build/artefacts - # shellcheck disable=SC2039 - IFS='|' read -ra BUILD_PAIRS <<< "$BUILD_IN" - # shellcheck disable=SC2039 - for BUILD_PAIR in "${BUILD_PAIRS[@]}" - do - # shellcheck disable=SC2039 - IFS=';' read -ra PARSED_PAIR <<< "$BUILD_PAIR" - # shellcheck disable=SC2039 - PLATFORM=${PARSED_PAIR[0]} - # shellcheck disable=SC2039 - ARCH=${PARSED_PAIR[1]} - - GMP_LIPOARGS="" - RELIC_LIPOARGS="" - BLS_LIPOARGS="" - - # shellcheck disable=SC2039 - local NEED_LIPO=0 - # shellcheck disable=SC2039 - IFS='+' read -ra ARCHS <<< "$ARCH" - # shellcheck disable=SC2039 - for i in "${!ARCHS[@]}" - do - # shellcheck disable=SC2039 - local SINGLEARCH=${ARCHS[i]} - - # build for every platform+arch - build_all_arch "$PLATFORM" "$SINGLEARCH" - - PFX="${PLATFORM}"-"${SINGLEARCH}" - ARCH_TARGET_DIR=${TARGET_DIR}/${PFX} - rm -rf "${ARCH_TARGET_DIR}" - mkdir -p "${ARCH_TARGET_DIR}" - #mv "${BUILD}/gmplib-${PFX}/lib/libgmp.a" "${ARCH_TARGET_DIR}/libgmp.a" - #mv "${BUILD}/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" "${ARCH_TARGET_DIR}/librelic.a" - #mv "${BUILD}/bls-${PFX}/libbls.a" "${ARCH_TARGET_DIR}/libbls.a" - - libtool -static -o "${ARCH_TARGET_DIR}/libbls.a" \ - "${BUILD}/gmplib-${PFX}/lib/libgmp.a" \ - "${BUILD}/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" \ - "${BUILD}/bls-${PFX}/libbls.a" - - # shellcheck disable=SC2039 - GMP_LIPOARGS+="${ARCH_TARGET_DIR}/libgmp.a " - # shellcheck disable=SC2039 - RELIC_LIPOARGS+="${ARCH_TARGET_DIR}/librelic.a " - # shellcheck disable=SC2039 - BLS_LIPOARGS+="${ARCH_TARGET_DIR}/libbls.a " - - NEED_LIPO=i - done - - # Do lipo if we need https://developer.apple.com/forums/thread/666335?answerId=645963022#645963022 -# if [[ $NEED_LIPO -gt 0 ]] -# then -# FAT_TARGET_DIR=${TARGET_DIR}/${PLATFORM}-fat -# rm -rf "${FAT_TARGET_DIR}" -# mkdir -p "${FAT_TARGET_DIR}" -# # shellcheck disable=SC2086 -# xcrun lipo $GMP_LIPOARGS -create -output "${FAT_TARGET_DIR}/libgmp.a" -# # shellcheck disable=SC2086 -# xcrun lipo $RELIC_LIPOARGS -create -output "${FAT_TARGET_DIR}/librelic.a" -# # shellcheck disable=SC2086 -# xcrun lipo $BLS_LIPOARGS -create -output "${FAT_TARGET_DIR}/libbls.a" -# libtool -static -o "${FAT_TARGET_DIR}/libbls_combined.a" "${FAT_TARGET_DIR}/libgmp.a" "${FAT_TARGET_DIR}/librelic.a" "${FAT_TARGET_DIR}/libbls.a" -# rm "${FAT_TARGET_DIR}/libgmp.a" -# rm "${FAT_TARGET_DIR}/librelic.a" -# rm "${FAT_TARGET_DIR}/libbls.a" -# mv "${FAT_TARGET_DIR}/libbls_combined.a" "${FAT_TARGET_DIR}/libbls.a" -# # clean up -# # shellcheck disable=SC2039 -# for i in "${!ARCHS[@]}" -# do -# local SINGLEARCH=${ARCHS[i]} -# rm -rf "${TARGET_DIR}-${SINGLEARCH}" -# done -# fi - done -} - -#make_relic_headers_universal() { -# RELIC_TARGET_DIR=relic-iphoneos-arm64 -# perl -p -e 's/#define WSIZE.*/#ifdef __LP64__\n#define WSIZE 64\n#else\n#define WSIZE 32\n#endif/' \ -# "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" \ -# > "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h.new" -# -# rm "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" -# mv "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h.new" "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" -#} - -#copy_headers() { -# mkdir build/artefacts/include -# # Copy all headers we will need -# cp -rf src/*.hpp build/artefacts/include -# cp -rf build/gmp/include/gmp.h build/artefacts/include -# cp -rf build/contrib/relic/include/*.h build/artefacts/include -# cp -rf build/contrib/relic/include/low/*.h build/artefacts/include -# cp -rf build/contrib/relic/relic-iphoneos-arm64/include/*.h build/artefacts/include -# rm -rf build/artefacts/include/test-utils.hpp -#} - -#function make_fat_binary() -#{ -# pushd artefacts -# -# XCFRAMEWORK_ARGS="" -# -# for dir in */; do -# if [ -d "$dir" ]; then -# if [[ "$dir" != "include/" ]]; then -# libtool -static -o "${dir}libbls_combined.a" "${dir}libgmp.a" "${dir}librelic.a" "${dir}libbls.a" -# -# XCFRAMEWORK_ARGS+="-library ${dir}libbls_combined.a -headers include " -# fi -# fi -# done -# -# #xcodebuild -create-xcframework $XCFRAMEWORK_ARGS -output "libbls.xcframework" -#} - -prepare -build_all "${MACOS};x86_64+arm64" -build_all "${IPHONEOS};arm64|${IPHONESIMULATOR};arm64+x86_64" - -#make_relic_headers_universal -#copy_headers -#make_fat_binary diff --git a/apple.rust.single.sh b/apple.rust.single.sh deleted file mode 100755 index d99722bf02..0000000000 --- a/apple.rust.single.sh +++ /dev/null @@ -1,404 +0,0 @@ -#!/bin/sh -set -x -# "x86_64-apple-ios" -# "x86_64-apple-ios-sim" -# "aarch64-apple-ios" -# "aarch64-apple-ios-sim" -# "x86_64-apple-darwin" -# "aarch64-apple-darwin" -# TODO: it's probably needs to be optimized in order to increase better build velocity -# TODO: so we need to combine multiple targets -TARGET=$1 -git submodule update --init -MIN_IOS="13.0" -MIN_WATCHOS="5.0" -MIN_TVOS=$MIN_IOS -MIN_MACOS="10.15" - -IPHONEOS=iphoneos -IPHONESIMULATOR=iphonesimulator -WATCHOS=watchos -WATCHSIMULATOR=watchsimulator -TVOS=appletvos -TVSIMULATOR=appletvsimulator -MACOS=macosx - -LOGICALCPU_MAX=$(sysctl -n hw.logicalcpu_max) -BUILD=build - -version_min_flag() { - PLATFORM=$1 - FLAG="" - # shellcheck disable=SC2039 - # shellcheck disable=SC2053 - if [[ $PLATFORM = $IPHONEOS ]]; then - FLAG="-miphoneos-version-min=${MIN_IOS}" - elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then - FLAG="-mios-simulator-version-min=${MIN_IOS}" - elif [[ $PLATFORM = $WATCHOS ]]; then - FLAG="-mwatchos-version-min=${MIN_WATCHOS}" - elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then - FLAG="-mwatchos-simulator-version-min=${MIN_WATCHOS}" - elif [[ $PLATFORM = $TVOS ]]; then - FLAG="-mtvos-version-min=${MIN_TVOS}" - elif [[ $PLATFORM = $TVSIMULATOR ]]; then - FLAG="-mtvos-simulator-version-min=${MIN_TVOS}" - elif [[ $PLATFORM = $MACOS ]]; then - FLAG="-mmacosx-version-min=${MIN_MACOS}" - fi - echo $FLAG -} - - -prepare() { - download_gmp() { - GMP_VERSION="6.2.1" - CURRENT_DIR=$(pwd) - echo "$CURRENT_DIR" - # shellcheck disable=SC2039,SC2164 - pushd ${BUILD} - mkdir -p "contrib" - if [ ! -s "contrib/gmp-${GMP_VERSION}.tar.bz2" ]; then - curl -L -o "contrib/gmp-${GMP_VERSION}.tar.bz2" https://gmplib.org/download/gmp/gmp-${GMP_VERSION}.tar.bz2 - fi - rm -rf "contrib/gmp" - # shellcheck disable=SC2039,SC2164 - pushd contrib - tar xfj "gmp-${GMP_VERSION}.tar.bz2" - mv gmp-${GMP_VERSION} gmp - rm gmp/compat.c && cp ../../contrib/gmp-patch-6.2.1/compat.c gmp/compat.c - rm gmp/longlong.h && cp ../../contrib/gmp-patch-6.2.1/longlong.h gmp/longlong.h - # shellcheck disable=SC2039,SC2164 - popd #contrib - # shellcheck disable=SC2039,SC2164 - popd #build - } - - download_cmake_toolchain() { - if [ ! -s "${BUILD}/ios.toolchain.cmake" ]; then - SHA256_HASH="d02857ff6bd64f1d7109ca59c3e4f3b2f89d0663c412146e6977c679801b3243" - curl -o "${BUILD}/ios.toolchain.cmake" https://raw.githubusercontent.com/leetal/ios-cmake/c55677a4445b138c9ef2650d3c21f22cc78c2357/ios.toolchain.cmake - DOWNLOADED_HASH=$(shasum -a 256 ${BUILD}/ios.toolchain.cmake | cut -f 1 -d " ") - if [ $SHA256_HASH != "$DOWNLOADED_HASH" ]; then - echo "Error: sha256 checksum of ios.toolchain.cmake mismatch" >&2 - exit 1 - fi - fi - } - - download_relic() { - CURRENT_DIR=$(pwd) - echo "$CURRENT_DIR" - mkdir -p "${CURRENT_DIR}/${BUILD}/contrib" - if [ ! -s "${CURRENT_DIR}/${BUILD}/contrib/relic" ]; then - # shellcheck disable=SC2039,SC2164 - pushd "${CURRENT_DIR}/${BUILD}/contrib" - git clone --depth 1 --branch "feat/ios-support" https://github.com/pankcuf/relic - # shellcheck disable=SC2039,SC2164 - pushd relic - git fetch --depth 1 origin 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae - git checkout 19fb6d79a77ade4ae8cd70d2b0ef7aab8720d1ae - # shellcheck disable=SC2039,SC2164 - popd #relic - # shellcheck disable=SC2039,SC2164 - popd #contrib - fi - } - rm -rf ${BUILD} - mkdir -p ${BUILD} - download_relic - download_gmp - download_cmake_toolchain -} - -build_gmp_arch() { - PLATFORM=$1 - ARCH=$2 - PFX=${PLATFORM}-${ARCH} - # why this works with this host only? - HOST=arm-apple-darwin - # shellcheck disable=SC2039,SC2164 - pushd ${BUILD} - SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) - PLATFORM_PATH=$(xcrun --sdk "$PLATFORM" --show-sdk-platform-path) - CLANG=$(xcrun --sdk "$PLATFORM" --find clang) - DEVELOPER=$(xcode-select --print-path) - CURRENT_DIR=$(pwd) - export PATH="${PLATFORM_PATH}/Developer/usr/bin:${DEVELOPER}/usr/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/opt/homebrew/bin" - mkdir gmplib-"${PLATFORM}"-"${ARCH}" - CFLAGS="-Wno-unused-value -fembed-bitcode -arch ${ARCH} --sysroot=${SDK} $(version_min_flag "$PLATFORM")" - CONFIGURESCRIPT="gmp_configure_script.sh" - # shellcheck disable=SC2039,SC2164 - pushd contrib - # shellcheck disable=SC2039,SC2164 - pushd gmp - make clean || true - make distclean || true - echo "HOST: $HOST" - echo "PREFIX: ${CURRENT_DIR}/gmplib-${PFX}" - - cat >"$CONFIGURESCRIPT" << EOF -#!/bin/sh -./configure \ -CC="$CLANG" CFLAGS="$CFLAGS" CPPFLAGS="$CFLAGS" LDFLAGS="$CFLAGS" \ ---host=${HOST} --prefix="${CURRENT_DIR}/gmplib-${PFX}" \ ---disable-shared --enable-static --disable-assembly -v -EOF - - chmod a+x "$CONFIGURESCRIPT" - sh "$CONFIGURESCRIPT" - rm "$CONFIGURESCRIPT" - - # shellcheck disable=SC2039 - mkdir -p "${CURRENT_DIR}/log" - # shellcheck disable=SC2039 - make -j "$LOGICALCPU_MAX" &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-build.log - # shellcheck disable=SC2039 - make install &> "${CURRENT_DIR}"/log/gmplib-"${PFX}"-install.log - # shellcheck disable=SC2039,SC2164 - popd # gmp - # shellcheck disable=SC2039,SC2164 - popd # contrib - # shellcheck disable=SC2039,SC2164 - popd # build -} - -build_relic_arch() { - PLATFORM=$1 - ARCH=$2 - PFX=${PLATFORM}-${ARCH} - - # shellcheck disable=SC2039,SC2164 - pushd ${BUILD} - - SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) - - BUILDDIR=relic-"${PFX}" - TOOLCHAIN=$(pwd)/ios.toolchain.cmake - GMP_PFX=$(pwd)/gmplib-${PFX} - rm -rf "$BUILDDIR" - mkdir "$BUILDDIR" - # shellcheck disable=SC2039,SC2164 - pushd "$BUILDDIR" - - unset CC - # shellcheck disable=SC2155 - export CC=$(xcrun --sdk "${PLATFORM}" --find clang) - - WSIZE=0 - IOS_PLATFORM="" - OPTIMIZATIONFLAGS="" - DEPLOYMENT_TARGET="" - - # shellcheck disable=SC2039 - # shellcheck disable=SC2053 - if [[ $PLATFORM = $IPHONEOS ]]; then - if [[ $ARCH = "arm64" ]] || [[ $ARCH = "arm64e" ]]; then - IOS_PLATFORM=OS64 - DEPLOYMENT_TARGET=$MIN_IOS - WSIZE=64 - OPTIMIZATIONFLAGS=-fomit-frame-pointer - else - IOS_PLATFORM=OS - WSIZE=32 - fi - elif [[ $PLATFORM = $IPHONESIMULATOR ]]; then - if [[ $ARCH = "x86_64" ]]; then - IOS_PLATFORM=SIMULATOR64 - DEPLOYMENT_TARGET=$MIN_IOS - WSIZE=64 - OPTIMIZATIONFLAGS=-fomit-frame-pointer - elif [[ $ARCH = "arm64" ]]; then - IOS_PLATFORM=SIMULATORARM64 - DEPLOYMENT_TARGET=$MIN_IOS - WSIZE=64 - else - IOS_PLATFORM=SIMULATOR - WSIZE=32 - fi - elif [[ $PLATFORM = $WATCHOS ]]; then - IOS_PLATFORM=WATCHOS - DEPLOYMENT_TARGET=$MIN_WATCHOS - WSIZE=32 - elif [[ $PLATFORM = $WATCHSIMULATOR ]]; then - IOS_PLATFORM=SIMULATOR_WATCHOS - DEPLOYMENT_TARGET=$MIN_WATCHOS - WSIZE=32 - elif [[ $PLATFORM = $TVOS ]]; then - IOS_PLATFORM=TVOS - DEPLOYMENT_TARGET=$MIN_TVOS - WSIZE=64 - OPTIMIZATIONFLAGS=-fomit-frame-pointer - elif [[ $PLATFORM = $TVSIMULATOR ]]; then - IOS_PLATFORM=SIMULATOR_TVOS - #TODO - if [[ $ARCH = "arm64" ]] - then - IOS_PLATFORM=OS64 - fi - DEPLOYMENT_TARGET=$MIN_TVOS - WSIZE=64 - OPTIMIZATIONFLAGS=-fomit-frame-pointer - elif [[ $PLATFORM = $MACOS ]]; then - WSIZE=64 - IOS_PLATFORM=MAC - if [[ $ARCH = "arm64" ]] - then - IOS_PLATFORM=MAC_ARM64 - fi - DEPLOYMENT_TARGET=$MIN_MACOS - OPTIMIZATIONFLAGS=-fomit-frame-pointer - fi - - COMPILER_ARGS="$(version_min_flag "$PLATFORM") -Wno-unused-functions" - - EXTRA_ARGS="-DOPSYS=NONE -DPLATFORM=$IOS_PLATFORM -DDEPLOYMENT_TARGET=$DEPLOYMENT_TARGET -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN" - - # shellcheck disable=SC2039 - if [[ $ARCH = "i386" ]]; then - EXTRA_ARGS+=" -DARCH=X86" - elif [[ $ARCH = "x86_64" ]]; then - EXTRA_ARGS+=" -DARCH=X64" - else - EXTRA_ARGS+=" -DARCH=ARM" - if [[ $ARCH = "armv7s" ]]; then - EXTRA_ARGS+=" -DIOS_ARCH=armv7s" - elif [[ $ARCH = "armv7k" ]]; then - EXTRA_ARGS+=" -DIOS_ARCH=armv7k" - elif [[ $ARCH = "arm64_32" ]]; then - EXTRA_ARGS+=" -DIOS_ARCH=arm64_32" - fi - fi - - CURRENT_DIR=$(pwd) - cmake -DCMAKE_PREFIX_PATH:PATH="${GMP_PFX}" -DTESTS=0 -DBENCH=0 -DBUILD_BLS_JS_BINDINGS=0 -DBUILD_BLS_PYTHON_BINDINGS=0 \ - -DBUILD_BLS_BENCHMARKS=0 -DBUILD_BLS_TESTS=0 -DCHECK=off -DARITH=gmp -DTIMER=HPROC -DFP_PRIME=381 -DMULTI=PTHREAD \ - -DFP_QNRES=on -DFP_METHD="INTEG;INTEG;INTEG;MONTY;EXGCD;SLIDE" -DFPX_METHD="INTEG;INTEG;LAZYR" -DPP_METHD="LAZYR;OATEP" \ - -DCOMP_FLAGS="-pipe -std=c99 -O3 -funroll-loops $OPTIMIZATIONFLAGS -isysroot $SDK -arch $ARCH -fembed-bitcode ${COMPILER_ARGS}" \ - -DWSIZE=$WSIZE -DVERBS=off -DSHLIB=off -DALLOC="AUTO" -DEP_PLAIN=off -DEP_SUPER=off -DPP_EXT="LAZYR" \ - -DWITH="DV;BN;MD;FP;EP;FPX;EPX;PP;PC;CP" -DBN_METHD="COMBA;COMBA;MONTY;SLIDE;STEIN;BASIC" ${EXTRA_ARGS} ../../ - - make -j "$LOGICALCPU_MAX" - # shellcheck disable=SC2039,SC2164 - popd # "$BUILDDIR" - # shellcheck disable=SC2039,SC2164 - popd # contrib/relic -} - -build_bls_arch() { - # shellcheck disable=SC2039 - BLS_FILES=( "bls" "chaincode" "elements" "extendedprivatekey" "extendedpublickey" "legacy" "privatekey" "schemes" "threshold" ) - # shellcheck disable=SC2039 - ALL_BLS_OBJ_FILES=$(printf "%s.o " "${BLS_FILES[@]}") - - PLATFORM=$1 - ARCH=$2 - PFX=${PLATFORM}-${ARCH} - SDK=$(xcrun --sdk "$PLATFORM" --show-sdk-path) - - BUILDDIR=${BUILD}/bls-"${PFX}" - rm -rf "$BUILDDIR" - mkdir "$BUILDDIR" - # shellcheck disable=SC2039,SC2164 - pushd "$BUILDDIR" - - EXTRA_ARGS="$(version_min_flag "$PLATFORM")" - - CURRENT_DIR=$(pwd) - - # shellcheck disable=SC2039 - for F in "${BLS_FILES[@]}" - do - clang -I"../contrib/relic/include" \ - -I"../relic-${PFX}/_deps/relic-build/include" \ - -I"../../src/" \ - -I"../gmplib-${PFX}/include" \ - -x c++ -std=c++14 -stdlib=libc++ -fembed-bitcode -arch "${ARCH}" -isysroot "${SDK}" "${EXTRA_ARGS}" \ - -c "../../src/${F}.cpp" -o "${F}.o" - done - - # shellcheck disable=SC2086 - xcrun -sdk "$PLATFORM" ar -cvq libbls.a $ALL_BLS_OBJ_FILES - - # shellcheck disable=SC2039,SC2164 - popd # "$BUILDDIR" -} - -build_all_arch() { - PLATFORM=$1 - ARCH=$2 - build_gmp_arch "$PLATFORM" "$ARCH" - build_relic_arch "$PLATFORM" "$ARCH" - build_bls_arch "$PLATFORM" "$ARCH" -} - -build_target() { - BUILD_IN=$1 - echo "Build target: $BUILD_IN" - ARCH="" - PLATFORM="" - # shellcheck disable=SC2039 - if [[ $BUILD_IN = "x86_64-apple-ios" ]]; then - ARCH=x86_64 - PLATFORM=$IPHONESIMULATOR - elif [[ $BUILD_IN = "aarch64-apple-ios" ]]; then - ARCH=arm64 - PLATFORM=$IPHONEOS - elif [[ $BUILD_IN = "aarch64-apple-ios-sim" ]]; then - ARCH=arm64 - PLATFORM=$IPHONESIMULATOR - elif [[ $BUILD_IN = "x86_64-apple-darwin" ]]; then - ARCH=x86_64 - PLATFORM=$MACOS - elif [[ $BUILD_IN = "aarch64-apple-darwin" ]]; then - ARCH=arm64 - PLATFORM=$MACOS - fi - build_all_arch "$PLATFORM" "$ARCH" - PFX="${PLATFORM}"-"${ARCH}" - rm -rf "build/artefacts/${BUILD_IN}" - mkdir -p "build/artefacts/${BUILD_IN}/include" -# libtool -static -o "build/artefacts/${BUILD_IN}/libbls.a" \ -# "build/gmplib-${PFX}/lib/libgmp.a" \ -# "build/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" \ -# "build/bls-${PFX}/libbls.a" - cp "build/gmplib-${PFX}/lib/libgmp.a" "build/artefacts/${BUILD_IN}" - cp "build/relic-${PFX}/_deps/relic-build/lib/librelic_s.a" "build/artefacts/${BUILD_IN}" - cp "build/relic-${PFX}/_deps/sodium-build/libsodium.a" "build/artefacts/${BUILD_IN}" - cp "build/bls-${PFX}/libbls.a" "build/artefacts/${BUILD_IN}" - cp -rf build/bls-"${PFX}"/*.o build/artefacts/"${BUILD_IN}"/include - cp -rf src/*.hpp build/artefacts/"${BUILD_IN}"/include - cp -rf build/gmplib-"${PFX}"/include/gmp.h build/artefacts/"${BUILD_IN}"/include - cp -rf build/relic-"${PFX}"/_deps/relic-build/include/*.h build/artefacts/"${BUILD_IN}"/include -} - -#make_relic_headers_universal() { -# RELIC_TARGET_DIR=relic-iphoneos-arm64 -# perl -p -e 's/#define WSIZE.*/#ifdef __LP64__\n#define WSIZE 64\n#else\n#define WSIZE 32\n#endif/' \ -# "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" \ -# > "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h.new" -# -# rm "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" -# mv "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h.new" "build/contrib/relic/${RELIC_TARGET_DIR}/include/relic_conf.h" -#} -# -#copy_headers() { -## mkdir build/artefacts/include -# # Copy all headers we will need -# cp -rf src/*.hpp ${BUILD}/artefacts/include -# cp -rf ${BUILD}/contrib/gmp/include/gmp.h ${BUILD}/artefacts/include -# cp -rf ${BUILD}/contrib/relic/include/*.h ${BUILD}/artefacts/include -# cp -rf ${BUILD}/contrib/relic/include/low/*.h ${BUILD}/artefacts/include -# #cp -rf ${BUILD}/contrib/relic/relic-iphoneos-arm64/include/*.h ${BUILD}/artefacts/include -# rm -rf ${BUILD}/artefacts/include/test-utils.hpp -#} - -prepare -build_target "$TARGET" -#copy_headers -#build_all "${MACOS};x86_64+arm64" -#build_all "${IPHONEOS};arm64|${IPHONESIMULATOR};arm64+x86_64" - -#make_relic_headers_universal -#copy_headers -#make_fat_binary diff --git a/configure.ac b/configure.ac index 23b61ec455..e60fca8fc1 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ([2.60]) -AC_INIT([libdashbls],[1.3.0]) +AC_INIT([libdashbls],[1.3.3]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_MACRO_DIR([build-aux/m4]) @@ -24,20 +24,21 @@ dnl make the compilation flags quiet unless V=1 is used m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) dnl Compiler checks (here before libtool). +if test "x${CFLAGS+set}" = "xset"; then + CFLAGS_overridden=yes +else + CFLAGS_overridden=no +fi if test "x${CXXFLAGS+set}" = "xset"; then CXXFLAGS_overridden=yes else CXXFLAGS_overridden=no fi + +AC_PROG_CC + AC_PROG_CXX -AM_PROG_CC_C_O - -AC_PROG_CC_C99 -if test x"$ac_cv_prog_cc_c99" = x"no"; then - AC_MSG_ERROR([c99 compiler support required]) -fi - dnl By default, libtool for mingw refuses to link static libs into a dll for dnl fear of mixing pic/non-pic objects, and import/export complications. Since dnl we have those under control, re-enable that functionality. @@ -58,24 +59,76 @@ AC_PATH_TOOL(STRIP, strip) AM_PROG_AS -AC_ARG_ENABLE(tests, - [AS_HELP_STRING([--disable-tests], - [do not compile tests (default is to compile)])], +AC_ARG_ENABLE([tests], + [AS_HELP_STRING([--enable-tests], + [Compile with tests [default=yes]])], [use_tests=$enableval], [use_tests=yes]) -AC_ARG_ENABLE(bench, - [AS_HELP_STRING([--disable-bench], - [do not compile benchmarks (default is to compile)])], +AC_ARG_ENABLE([bench], + [AS_HELP_STRING([--enable-bench], + [Compile with benchmarks [default=yes]])], [use_bench=$enableval], [use_bench=yes]) AC_ARG_ENABLE([hardening], - [AS_HELP_STRING([--disable-hardening], - [do not attempt to harden the resulting executables (default is to harden when possible)])], + [AS_HELP_STRING([--enable-hardening], + [Enable hardening flags and arguments [default=auto]])], [use_hardening=$enableval], [use_hardening=auto]) +AC_ARG_ENABLE([optimizations], + [AS_HELP_STRING([--enable-optimizations], + [Enable compiler and library optimizations [default=yes]])], + [use_optimizations=$enableval], + [use_optimizations=yes]) + +AC_ARG_ENABLE([debug], + [AS_HELP_STRING([--enable-debug], + [Build with debugging support [default=no]])], + [use_debug=$enableval], + [use_debug=no]) + +AC_LANG_PUSH([C]) + +dnl Check for a flag to turn compiler warnings into errors. This is helpful for checks which may +dnl appear to succeed because by default they merely emit warnings when they fail. +dnl +dnl Note that this is not necessarily a check to see if -Werror is supported, but rather to see if +dnl a compile with -Werror can succeed. This is important because the compiler may already be +dnl warning about something unrelated, for example about some path issue. If that is the case, +dnl -Werror cannot be used because all of those warnings would be turned into errors. +AX_CHECK_COMPILE_FLAG([-Werror], [FLAG_WERROR="-Werror"], [FLAG_WERROR=""]) + +if [[[ "$use_debug" == "yes" || "$use_optimizations" == "no" ]]]; then + dnl Clear default -g -O2 flags + if test x"$CFLAGS_overridden" = x"no"; then + CFLAGS="" + fi + if test x"$CXXFLAGS_overridden" = x"no"; then + CXXFLAGS="" + fi + + dnl Disable optimizations + AX_CHECK_COMPILE_FLAG([-O0], [[DEBUG_FLAGS="$DEBUG_FLAGS -O0"]], [], [[$FLAG_WERROR]]) + + if [[[ "$use_debug" == "yes" ]]]; then + dnl Prefer -g3, fall back to -g if that is unavailable. + AX_CHECK_COMPILE_FLAG( + [-g3], + [[DEBUG_FLAGS="$DEBUG_FLAGS -g3"]], + [AX_CHECK_COMPILE_FLAG([-g],[[DEBUG_FLAGS="$DEBUG_FLAGS -g"]])], [[$FLAG_WERROR]]) + + AX_CHECK_COMPILE_FLAG([-ftrapv],[DEBUG_FLAGS="$DEBUG_FLAGS -ftrapv"], [], [[$FLAG_WERROR]]) + else + dnl Reintroduce -g flag deleted during C(XX)FLAGS reset + AX_CHECK_COMPILE_FLAG([-g],[[DEBUG_FLAGS="$DEBUG_FLAGS -g"]], [], [[$FLAG_WERROR]]) + + dnl -ftrapv and -fwrapv conflict, so we only set this if use_debug=no + AX_CHECK_COMPILE_FLAG([-fwrapv],[DEBUG_FLAGS="$DEBUG_FLAGS -fwrapv"], [], [[$FLAG_WERROR]]) + fi +fi + dnl Define enum mappings for relic config AC_DEFINE([RLC_VERSION], ["0.5.0"], [Relic Version]) @@ -95,15 +148,56 @@ AC_DEFINE([GMP], [2], [Backend based on GNU Multiple Precision library.]) AC_DEFINE([GMP_SEC], [3], [Backend based on GNU Multiple Precision library, but using constant-time code.]) AC_DEFUN([GMP_CHECK],[ -if test x"$has_gmp" != x"yes"; then + AC_REQUIRE([AC_PROG_CC]) + CPPFLAGS_TEMP="$CPPFLAGS" CPPFLAGS="$GMP_CPPFLAGS $CPPFLAGS" LIBS_TEMP="$LIBS" LIBS="$GMP_LDFLAGS $LIBS" - AC_CHECK_HEADER(gmp.h,[AC_CHECK_LIB(gmp, __gmpz_init,[has_gmp=yes; GMP_LIBS="-lgmp";])]) + + AC_CHECK_HEADER( + gmp.h, + [AC_CHECK_LIB(gmp, __gmpz_init, [], [gmp_fail_reason="libgmp not found or unusable"; has_gmp=no;])], + [gmp_fail_reason="gmp header not found"; has_gmp=no;] + ) + + if test x"$has_gmp" != x"no"; then + # Proper support for macOS aarch64 was introduced in 6.3.0, but LTS distros + # like Ubuntu 20.04 (focal) use 6.2.0, so, the minimum supported version is + # determined by platform and architecture. + case $host in + *darwin*) + case $host_cpu in + aarch*) + gmp_major_version=6 + gmp_minor_version=3 + ;; + esac + ;; + *) + gmp_major_version=6 + gmp_minor_version=2 + ;; + esac + AC_MSG_CHECKING([gmp version >= $gmp_major_version.$gmp_minor_version]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[@%:@include ]], + [[ + @%:@if __GNU_MP_VERSION < $gmp_major_version || __GNU_MP_VERSION_MINOR < $gmp_minor_version + @%:@error Unsupported GMP version + @%:@endif]])], + [AC_MSG_RESULT([yes]); GMP_LIBS="-lgmp"; has_gmp=yes;], + [AC_MSG_RESULT([no]); gmp_fail_reason="unsupported gmp version"; has_gmp=no;] + ) + fi + + if test x"$want_backend" = x"gmp" && test x"$has_gmp" = x"no"; then + AC_MSG_ERROR([$gmp_fail_reason]) + fi + CPPFLAGS="$CPPFLAGS_TEMP" LIBS="$LIBS_TEMP" -fi ]) AC_ARG_WITH([backend], @@ -113,34 +207,38 @@ AC_ARG_WITH([backend], [want_backend=auto] ) +case $host in + *darwin*) + AC_PATH_PROG([BREW],brew,) + if test x$BREW != x; then + # These Homebrew packages may be keg-only, meaning that they won't be found + # in expected paths because they may conflict with system files. Ask + # Homebrew where each one is located, then adjust paths accordingly. + gmp_prefix=`$BREW --prefix gmp 2>/dev/null` + if test x$gmp_prefix != x; then + GMP_CPPFLAGS="-I$gmp_prefix/include" + GMP_LDFLAGS="-L$gmp_prefix/lib" + fi + fi + ;; +esac + if test x"$want_backend" = x"auto"; then - GMP_CHECK - if test x"$has_gmp" = x"yes"; then - case $host in - *darwin*) - case $host_cpu in - aarch*) - want_backend=easy - ;; - *) - want_backend=gmp - ;; - esac - ;; - *) - want_backend=gmp - ;; - esac - else + if test x"$use_optimizations" = x"no"; then want_backend=easy + else + GMP_CHECK + if test x"$has_gmp" = x"yes"; then + want_backend=gmp + else + want_backend=easy + fi fi else case $want_backend in gmp) + dnl GMP_CHECK will report the reason if and why the backend cannot be used. GMP_CHECK - if test x"$has_gmp" != x"yes"; then - AC_MSG_ERROR([gmp backend explicitly requested but libgmp not available]) - fi ;; easy) ;; @@ -257,20 +355,14 @@ AC_DEFINE([BRUCH], [6], [Hardware-friendly inversion by Brunner-Curiger-Hofste AC_DEFINE([CTAIA], [7], [Constant-time version of almost inverse.]) AC_DEFINE([LOWER], [8], [Use implementation provided by the lower layer.]) -dnl Define relic switches -AC_ARG_ENABLE([debug], - [AS_HELP_STRING([--enable-debug], - [Build with debugging support (default is no)])], - [use_debug=$enableval], - [use_debug=no]) - -if test x$use_debug = xyes; then +if test x"$use_debug" = x"yes"; then AC_DEFINE([DEBUG], [1], [Define this symbol if debugging support is enabled]) fi +dnl Define relic switches AC_ARG_ENABLE([profiling], [AS_HELP_STRING([--enable-profiling], - [Build with profiling support (default is no)])], + [Build with profiling support [default=no]])], [use_profiling=$enableval], [use_profiling=no]) @@ -280,7 +372,7 @@ fi AC_ARG_ENABLE([check], [AS_HELP_STRING([--enable-check], - [Build with error-checking support (default is no)])], + [Build with error-checking support [default=no]])], [use_check=$enableval], [use_check=no]) @@ -290,7 +382,7 @@ fi AC_ARG_ENABLE([verbs], [AS_HELP_STRING([--enable-verbs], - [Build with detailed error messages (default is no)])], + [Build with detailed error messages [default=no]])], [use_verbs=$enableval], [use_verbs=no]) @@ -300,7 +392,7 @@ fi AC_ARG_ENABLE([overhead], [AS_HELP_STRING([--enable-overhead], - [Build with overhead estimation (default is no)])], + [Build with overhead estimation [default=no]])], [use_overhead=$enableval], [use_overhead=no]) @@ -310,7 +402,7 @@ fi AC_ARG_ENABLE([quiet], [AS_HELP_STRING([--enable-quiet], - [Build with printing disabled (default is yes)])], + [Build with printing disabled [default=yes]])], [use_quiet=$enableval], [use_quiet=yes]) @@ -320,7 +412,7 @@ fi AC_ARG_ENABLE([color], [AS_HELP_STRING([--enable-color], - [Build with colored output support (default is yes)])], + [Build with colored output support [default=yes]])], [use_color=$enableval], [use_color=yes]) @@ -330,7 +422,7 @@ fi AC_ARG_ENABLE([big_endian], [AS_HELP_STRING([--enable-big-endian], - [Build with big-endian support (default is no)])], + [Build with big-endian support [default=no]])], [use_big_endian=$enableval], [use_big_endian=no]) @@ -340,63 +432,46 @@ fi use_pkgconfig=yes -case $host_cpu in - x86_64) - dnl Support for AMD64 (also known as x86_64 on some platforms) processors - CPU_ARCH="x64" - AC_DEFINE([ARCH], [X64], [Architecture.]) - AC_DEFINE([WSIZE], [64], [Size of word in this architecture.]) - ;; - aarch*) - dnl Relic doesn't support aarch64 yet, set CPU_ARCH to none. - dnl Support for 64-bit ARM processors - CPU_ARCH="none" - AC_DEFINE([ARCH], [ARM], [Architecture.]) - AC_DEFINE([WSIZE], [64], [Size of word in this architecture.]) - ;; - i?86) - dnl Support for Intel x86 processors - CPU_ARCH="x86" - AC_DEFINE([ARCH], [X86], [Architecture.]) - AC_DEFINE([WSIZE], [32], [Size of word in this architecture.]) - ;; - arm*) - dnl Support for 32-bit native ARM processors - CPU_ARCH="arm" - AC_DEFINE([ARCH], [ARM], [Architecture.]) - AC_DEFINE([WSIZE], [32], [Size of word in this architecture.]) - ;; - *32*) - dnl Support for an undefined 32-bit architecture - CPU_ARCH="none" - AC_DEFINE([ARCH], [RELIC_NONE], [Architecture.]) - AC_DEFINE([WSIZE], [32], [Size of word in this architecture.]) - ;; - *64*) - dnl Support for an undefined 64-bit architecture - CPU_ARCH="none" - AC_DEFINE([ARCH], [RELIC_NONE], [Architecture.]) - AC_DEFINE([WSIZE], [64], [Size of word in this architecture.]) - ;; - *) - AC_MSG_ERROR([Unable to determine host architecture, may not be supported!]) - ;; -esac +if [[[ "$host_cpu" == x86_64 && "$use_optimizations" == "yes" ]]]; then + dnl Support for AMD64 (also known as x86_64 on some platforms) processors + CPU_ARCH="x64" + AC_DEFINE([ARCH], [X64], [Architecture.]) + AC_DEFINE([WSIZE], [64], [Size of word in this architecture.]) +elif [[[ "$host_cpu" == aarch* && "$use_optimizations" == "yes" ]]]; then + dnl Support for 64-bit ARM processors + dnl Relic doesn't support aarch64 yet, set CPU_ARCH to none and ARCH to RELIC_NONE. + CPU_ARCH="none" + AC_DEFINE([ARCH], [RELIC_NONE], [Architecture.]) + AC_DEFINE([WSIZE], [64], [Size of word in this architecture.]) +elif [[[ "$host_cpu" == i?86 && "$use_optimizations" == "yes" ]]]; then + dnl Support for Intel x86 processors + CPU_ARCH="x86" + AC_DEFINE([ARCH], [X86], [Architecture.]) + AC_DEFINE([WSIZE], [32], [Size of word in this architecture.]) +elif [[[ "$host_cpu" == arm* && "$use_optimizations" == "yes" ]]]; then + dnl Support for 32-bit native ARM processors + CPU_ARCH="arm" + AC_DEFINE([ARCH], [ARM], [Architecture.]) + AC_DEFINE([WSIZE], [32], [Size of word in this architecture.]) +elif [[[ "$host_cpu" == *64* ]]]; then + dnl Support for an undefined 64-bit architecture + CPU_ARCH="none" + AC_DEFINE([ARCH], [RELIC_NONE], [Architecture.]) + AC_DEFINE([WSIZE], [64], [Size of word in this architecture.]) +elif [[[ "$host_cpu" == *32* || "$host_cpu" == arm* || "$host_cpu" == i?86 ]]]; then + dnl Support for an undefined 32-bit architecture + CPU_ARCH="none" + AC_DEFINE([ARCH], [RELIC_NONE], [Architecture.]) + AC_DEFINE([WSIZE], [32], [Size of word in this architecture.]) +else + AC_MSG_ERROR([Unable to determine host architecture, may not be supported!]) +fi case $host in *darwin*) AC_DEFINE([OPSYS], [MACOSX], [Detected operation system.]) AC_PATH_PROG([BREW],brew,) - if test x$BREW != x; then - # These Homebrew packages may be keg-only, meaning that they won't be found - # in expected paths because they may conflict with system files. Ask - # Homebrew where each one is located, then adjust paths accordingly. - gmp_prefix=`$BREW --prefix gmp 2>/dev/null` - if test x$gmp_prefix != x; then - GMP_CPPFLAGS="-I$gmp_prefix/include" - GMP_LDFLAGS="-L$gmp_prefix/lib" - fi - else + if test x$BREW = x; then AC_PATH_PROG([PORT],port,) # If homebrew isn't installed and macports is, add the macports default paths # as a last resort. @@ -480,17 +555,20 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([[char foo;]])], CFLAGS="$saved_CFLAGS" ]) -AC_LANG_PUSH([C]) -AX_CHECK_COMPILE_FLAG([-Wall],[WARN_CFLAGS="$WARN_CFLAGS -Wall"],,) -AX_CHECK_COMPILE_FLAG([-Wextra],[WARN_CFLAGS="$WARN_CFLAGS -Wextra"],,) -AX_CHECK_COMPILE_FLAG([-Wcast-align],[WARN_CFLAGS="$WARN_CFLAGS -Wcast-align"],,) -AX_CHECK_COMPILE_FLAG([-Wunused-parameter],[NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-unused-parameter"],,) -AX_CHECK_COMPILE_FLAG([-Wshadow],[NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-shadow"],,) -AX_CHECK_COMPILE_FLAG([-Wsign-compare],[NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-sign-compare"],,) -AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes],[NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-strict-prototypes"],,) -AX_CHECK_COMPILE_FLAG([-Wunused-function],[NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-unused-function"],,) -AX_CHECK_COMPILE_FLAG([-Wlong-long],[NOWARN_CFLAGS="$NOWARN_CFLAGS -Wno-long-long"],,) -AC_LANG_POP([C]) +if [[[ "$CFLAGS_overridden" == "no" && "$CXXFLAGS_overridden" == "no" ]]]; then + dnl Enable warnings + AX_CHECK_COMPILE_FLAG([-Wall],[WARN_FLAGS="$WARN_FLAGS -Wall"], [], [[$FLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wcast-align],[WARN_FLAGS="$WARN_FLAGS -Wcast-align"], [], [[$FLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wextra],[WARN_FLAGS="$WARN_FLAGS -Wextra"], [], [[$FLAG_WERROR]]) + + dnl Exclude known warnings + AX_CHECK_COMPILE_FLAG([-Wlong-long],[NOWARN_FLAGS="$NOWARN_FLAGS -Wno-long-long"], [], [[$FLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wshadow],[NOWARN_FLAGS="$NOWARN_FLAGS -Wno-shadow"], [], [[$FLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wsign-compare],[NOWARN_FLAGS="$NOWARN_FLAGS -Wno-sign-compare"], [], [[$FLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wstrict-prototypes],[NOWARN_FLAGS="$NOWARN_FLAGS -Wno-strict-prototypes"], [], [[$FLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wunused-function],[NOWARN_FLAGS="$NOWARN_FLAGS -Wno-unused-function"], [], [[$FLAG_WERROR]]) + AX_CHECK_COMPILE_FLAG([-Wunused-parameter],[NOWARN_FLAGS="$NOWARN_FLAGS -Wno-unused-parameter"], [], [[$FLAG_WERROR]]) +fi dnl set default settings for relic AC_DEFINE([ALIGN], [1], [Byte boundary to align digit vectors.]) @@ -615,19 +693,19 @@ AC_SEARCH_LIBS([clock_gettime],[rt]) if test "$TARGET_OS" != "windows"; then dnl All windows code is PIC, forcing it on just adds useless compile warnings - AX_CHECK_COMPILE_FLAG([-fPIC], [PIC_FLAGS="-fPIC"]) + AX_CHECK_COMPILE_FLAG([-fPIC], [HARDENED_FLAGS="$HARDENED_FLAGS -fPIC"], [], [[$FLAG_WERROR]]) fi dnl All versions of gcc that we commonly use for building are subject to bug dnl https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90348. To work around that, set dnl -fstack-reuse=none for all gcc builds. (Only gcc understands this flag) -AX_CHECK_COMPILE_FLAG([-fstack-reuse=none], [HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-reuse=none"]) +AX_CHECK_COMPILE_FLAG([-fstack-reuse=none], [HARDENED_FLAGS="$HARDENED_FLAGS -fstack-reuse=none"], [], [[$FLAG_WERROR]]) if test "$use_hardening" != "no"; then use_hardening=yes - AX_CHECK_COMPILE_FLAG([-Wstack-protector], [HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -Wstack-protector"]) - AX_CHECK_COMPILE_FLAG([-fstack-protector-all], [HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-protector-all"]) + AX_CHECK_COMPILE_FLAG([-Wstack-protector], [HARDENED_FLAGS="$HARDENED_FLAGS -Wstack-protector"]) + AX_CHECK_COMPILE_FLAG([-fstack-protector-all], [HARDENED_FLAGS="$HARDENED_FLAGS -fstack-protector-all"], [], [[$FLAG_WERROR]]) - AX_CHECK_COMPILE_FLAG([-fcf-protection=full], [HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fcf-protection=full"]) + AX_CHECK_COMPILE_FLAG([-fcf-protection=full], [HARDENED_FLAGS="$HARDENED_FLAGS -fcf-protection=full"], [], [[$FLAG_WERROR]]) case $host in *mingw*) @@ -635,10 +713,16 @@ if test "$use_hardening" != "no"; then dnl See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90458 for more details. ;; *) - AX_CHECK_COMPILE_FLAG([-fstack-clash-protection], [HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -fstack-clash-protection"], [], []) + AX_CHECK_COMPILE_FLAG([-fstack-clash-protection], [HARDENED_FLAGS="$HARDENED_FLAGS -fstack-clash-protection"], [], [[$FLAG_WERROR]]) ;; esac + case $host in + *aarch64*) + AX_CHECK_COMPILE_FLAG([-mbranch-protection=bti], [HARDENED_CXXFLAGS="$HARDENED_CXXFLAGS -mbranch-protection=bti"], [], [[$CXXFLAG_WERROR]]) + ;; + esac + AX_CHECK_LINK_FLAG([-Wl,--enable-reloc-section], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--enable-reloc-section"], [], []) AX_CHECK_LINK_FLAG([-Wl,--dynamicbase], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--dynamicbase"], [], []) AX_CHECK_LINK_FLAG([-Wl,--nxcompat], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,--nxcompat"], [], []) @@ -646,7 +730,7 @@ if test "$use_hardening" != "no"; then AX_CHECK_LINK_FLAG([-Wl,-z,relro], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,relro"], [], []) AX_CHECK_LINK_FLAG([-Wl,-z,now], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,now"], [], []) AX_CHECK_LINK_FLAG([-Wl,-z,separate-code], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -Wl,-z,separate-code"], [], []) - AX_CHECK_LINK_FLAG([-fPIE -pie], [PIE_FLAGS="-fPIE"; HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"], [], []) + AX_CHECK_LINK_FLAG([-fPIE -pie], [HARDENED_FLAGS="$HARDENED_FLAGS -fPIE"; HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"], [], []) case $host in *mingw*) @@ -708,7 +792,9 @@ if test "$TARGET_OS" = "darwin"; then fi dnl Don't allow extended (non-ASCII) symbols in identifiers. This is easier for code review. -AX_CHECK_COMPILE_FLAG([-fno-extended-identifiers], [CORE_CXXFLAGS="$CORE_CXXFLAGS -fno-extended-identifiers"], [], []) +AX_CHECK_COMPILE_FLAG([-fno-extended-identifiers], [CORE_FLAGS="$CORE_FLAGS -fno-extended-identifiers"], [], [[$FLAG_WERROR]]) + +AC_LANG_POP([C]) AC_MSG_CHECKING([whether to build runtest]) if test x$use_tests = xyes; then @@ -753,24 +839,23 @@ AM_CONDITIONAL(WITH_FBX, test 1 -eq 1) AM_CONDITIONAL([USE_TESTS], [test x$BUILD_TEST = xyes]) AM_CONDITIONAL([USE_BENCH], [test x$BUILD_BENCH = xyes]) AM_CONDITIONAL([HARDEN], [test "$use_hardening" = "yes"]) +AM_CONDITIONAL([OPTIMIZE], [test "$use_optimizations" = "yes"]) AM_CONDITIONAL([ARITH_EASY], [test "$want_backend" = "easy"]) AM_CONDITIONAL([ARITH_GMP], [test "$want_backend" = "gmp"]) AC_SUBST(CPU_ARCH) +AC_SUBST(DEBUG_FLAGS) AC_SUBST(RAND_PATH, hashd) AC_SUBST(RELIC_CPPFLAGS) -AC_SUBST(WARN_CFLAGS) -AC_SUBST(NOWARN_CFLAGS) +AC_SUBST(WARN_FLAGS) +AC_SUBST(NOWARN_FLAGS) AC_SUBST(LIBTOOL_APP_LDFLAGS) -AC_SUBST(HARDENED_CXXFLAGS) -AC_SUBST(HARDENED_CPPFLAGS) +AC_SUBST(HARDENED_FLAGS) AC_SUBST(HARDENED_LDFLAGS) -AC_SUBST(PIC_FLAGS) -AC_SUBST(PIE_FLAGS) AC_SUBST(CORE_LDFLAGS) AC_SUBST(CORE_CPPFLAGS) -AC_SUBST(CORE_CXXFLAGS) +AC_SUBST(CORE_FLAGS) AC_SUBST(GMP_LDFLAGS) AC_SUBST(GMP_CPPFLAGS) @@ -784,3 +869,20 @@ AC_OUTPUT dnl Peplace conflict-prone PACKAGE-prefixed macros with DASHBLS sed -i.old 's/PACKAGE/DASHBLS/g' depends/relic/include/relic_conf.h sed -i.old 's/PACKAGE/DASHBLS/g' config.status + +echo +echo "Options used to compile and link:" +echo " target os = $TARGET_OS" +echo " backend = $want_backend" +echo " build bench = $BUILD_BENCH" +echo " build test = $BUILD_TEST" +echo " use debug = $use_debug" +echo " use hardening = $use_hardening" +echo " use optimizations = $use_optimizations" +echo +echo " LDFLAGS = $HARDENED_LDFLAGS $CORE_LDFLAGS $GMP_LDFLAGS" +echo " CFLAGS = $DEBUG_FLAGS $HARDENED_FLAGS $CORE_FLAGS $WARN_FLAGS $NOWARN_FLAGS" +echo " CPPFLAGS = $CORE_CPPFLAGS $GMP_CPPFLAGS" +echo " CXXFLAGS = $DEBUG_FLAGS $HARDENED_FLAGS $CORE_FLAGS $WARN_FLAGS $NOWARN_FLAGS" +echo " PTHREAD_FLAGS = $PTHREAD_CFLAGS $PTHREAD_LIBS" +echo diff --git a/contrib/gmp-patch-6.2.1/compat.c b/contrib/gmp-patch-6.2.1/compat.c deleted file mode 100644 index 3f563dd007..0000000000 --- a/contrib/gmp-patch-6.2.1/compat.c +++ /dev/null @@ -1,65 +0,0 @@ -/* Old function entrypoints retained for binary compatibility. - -Copyright 2000, 2001 Free Software Foundation, Inc. - -This file is part of the GNU MP Library. - -The GNU MP Library is free software; you can redistribute it and/or modify -it under the terms of either: - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your - option) any later version. - -or - - * the GNU General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - -or both in parallel, as here. - -The GNU MP Library is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received copies of the GNU General Public License and the -GNU Lesser General Public License along with the GNU MP Library. If not, -see https://www.gnu.org/licenses/. */ - -#include -#include "gmp-impl.h" - -/* RUNTIMECPUID */ -int bCheckedBMI = 0; -int bBMI1 = 0; -int bBMI2 = 0; -int bCheckedLZCNT = 0; -int bLZCNT = 0; - -/* mpn_divexact_by3 was a function in gmp 3.0.1, but as of gmp 3.1 it's a - macro calling mpn_divexact_by3c. */ -mp_limb_t -__MPN (divexact_by3) (mp_ptr dst, mp_srcptr src, mp_size_t size) -{ - return mpn_divexact_by3 (dst, src, size); -} - - -/* mpn_divmod_1 was a function in gmp 3.0.1 and earlier, but marked obsolete - in both gmp 2 and 3. As of gmp 3.1 it's a macro calling mpn_divrem_1. */ -mp_limb_t -__MPN (divmod_1) (mp_ptr dst, mp_srcptr src, mp_size_t size, mp_limb_t divisor) -{ - return mpn_divmod_1 (dst, src, size, divisor); -} - - -/* mpz_legendre was a separate function in gmp 3.1.1 and earlier, but as of - 4.0 it's a #define alias for mpz_jacobi. */ -int -__gmpz_legendre (mpz_srcptr a, mpz_srcptr b) -{ - return mpz_jacobi (a, b); -} diff --git a/contrib/gmp-patch-6.2.1/longlong.h b/contrib/gmp-patch-6.2.1/longlong.h deleted file mode 100644 index c0a7468919..0000000000 --- a/contrib/gmp-patch-6.2.1/longlong.h +++ /dev/null @@ -1,2355 +0,0 @@ -/* longlong.h -- definitions for mixed size 32/64 bit arithmetic. - -Copyright 1991-1994, 1996, 1997, 1999-2005, 2007-2009, 2011-2020 Free Software -Foundation, Inc. - -This file is part of the GNU MP Library. - -The GNU MP Library is free software; you can redistribute it and/or modify -it under the terms of either: - - * the GNU Lesser General Public License as published by the Free - Software Foundation; either version 3 of the License, or (at your - option) any later version. - -or - - * the GNU General Public License as published by the Free Software - Foundation; either version 2 of the License, or (at your option) any - later version. - -or both in parallel, as here. - -The GNU MP Library is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -for more details. - -You should have received copies of the GNU General Public License and the -GNU Lesser General Public License along with the GNU MP Library. If not, -see https://www.gnu.org/licenses/. */ - -/* You have to define the following before including this file: - - UWtype -- An unsigned type, default type for operations (typically a "word") - UHWtype -- An unsigned type, at least half the size of UWtype - UDWtype -- An unsigned type, at least twice as large a UWtype - W_TYPE_SIZE -- size in bits of UWtype - - SItype, USItype -- Signed and unsigned 32 bit types - DItype, UDItype -- Signed and unsigned 64 bit types - - On a 32 bit machine UWtype should typically be USItype; - on a 64 bit machine, UWtype should typically be UDItype. - - Optionally, define: - - LONGLONG_STANDALONE -- Avoid code that needs machine-dependent support files - NO_ASM -- Disable inline asm - - - CAUTION! Using this version of longlong.h outside of GMP is not safe. You - need to include gmp.h and gmp-impl.h, or certain things might not work as - expected. -*/ - -#define __BITS4 (W_TYPE_SIZE / 4) -#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) -#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) -#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) - -/* This is used to make sure no undesirable sharing between different libraries - that use this file takes place. */ -#ifndef __MPN -#define __MPN(x) __##x -#endif - -/* Define auxiliary asm macros. - - 1) umul_ppmm(high_prod, low_prod, multiplier, multiplicand) multiplies two - UWtype integers MULTIPLIER and MULTIPLICAND, and generates a two UWtype - word product in HIGH_PROD and LOW_PROD. - - 2) __umulsidi3(a,b) multiplies two UWtype integers A and B, and returns a - UDWtype product. This is just a variant of umul_ppmm. - - 3) udiv_qrnnd(quotient, remainder, high_numerator, low_numerator, - denominator) divides a UDWtype, composed by the UWtype integers - HIGH_NUMERATOR and LOW_NUMERATOR, by DENOMINATOR and places the quotient - in QUOTIENT and the remainder in REMAINDER. HIGH_NUMERATOR must be less - than DENOMINATOR for correct operation. If, in addition, the most - significant bit of DENOMINATOR must be 1, then the pre-processor symbol - UDIV_NEEDS_NORMALIZATION is defined to 1. - - 4) sdiv_qrnnd(quotient, remainder, high_numerator, low_numerator, - denominator). Like udiv_qrnnd but the numbers are signed. The quotient - is rounded towards 0. - - 5) count_leading_zeros(count, x) counts the number of zero-bits from the - msb to the first non-zero bit in the UWtype X. This is the number of - steps X needs to be shifted left to set the msb. Undefined for X == 0, - unless the symbol COUNT_LEADING_ZEROS_0 is defined to some value. - - 6) count_trailing_zeros(count, x) like count_leading_zeros, but counts - from the least significant end. - - 7) add_ssaaaa(high_sum, low_sum, high_addend_1, low_addend_1, - high_addend_2, low_addend_2) adds two UWtype integers, composed by - HIGH_ADDEND_1 and LOW_ADDEND_1, and HIGH_ADDEND_2 and LOW_ADDEND_2 - respectively. The result is placed in HIGH_SUM and LOW_SUM. Overflow - (i.e. carry out) is not stored anywhere, and is lost. - - 8) sub_ddmmss(high_difference, low_difference, high_minuend, low_minuend, - high_subtrahend, low_subtrahend) subtracts two two-word UWtype integers, - composed by HIGH_MINUEND_1 and LOW_MINUEND_1, and HIGH_SUBTRAHEND_2 and - LOW_SUBTRAHEND_2 respectively. The result is placed in HIGH_DIFFERENCE - and LOW_DIFFERENCE. Overflow (i.e. carry out) is not stored anywhere, - and is lost. - - If any of these macros are left undefined for a particular CPU, - C macros are used. - - - Notes: - - For add_ssaaaa the two high and two low addends can both commute, but - unfortunately gcc only supports one "%" commutative in each asm block. - This has always been so but is only documented in recent versions - (eg. pre-release 3.3). Having two or more "%"s can cause an internal - compiler error in certain rare circumstances. - - Apparently it was only the last "%" that was ever actually respected, so - the code has been updated to leave just that. Clearly there's a free - choice whether high or low should get it, if there's a reason to favour - one over the other. Also obviously when the constraints on the two - operands are identical there's no benefit to the reloader in any "%" at - all. - - */ - -/* The CPUs come in alphabetical order below. - - Please add support for more CPUs here, or improve the current support - for the CPUs below! */ - - -/* count_leading_zeros_gcc_clz is count_leading_zeros implemented with gcc - 3.4 __builtin_clzl or __builtin_clzll, according to our limb size. - Similarly count_trailing_zeros_gcc_ctz using __builtin_ctzl or - __builtin_ctzll. - - These builtins are only used when we check what code comes out, on some - chips they're merely libgcc calls, where we will instead want an inline - in that case (either asm or generic C). - - These builtins are better than an asm block of the same insn, since an - asm block doesn't give gcc any information about scheduling or resource - usage. We keep an asm block for use on prior versions of gcc though. - - For reference, __builtin_ffs existed in gcc prior to __builtin_clz, but - it's not used (for count_leading_zeros) because it generally gives extra - code to ensure the result is 0 when the input is 0, which we don't need - or want. */ - -#ifdef _LONG_LONG_LIMB -#define count_leading_zeros_gcc_clz(count,x) \ - do { \ - ASSERT ((x) != 0); \ - (count) = __builtin_clzll (x); \ - } while (0) -#else -#define count_leading_zeros_gcc_clz(count,x) \ - do { \ - ASSERT ((x) != 0); \ - (count) = __builtin_clzl (x); \ - } while (0) -#endif - -#ifdef _LONG_LONG_LIMB -#define count_trailing_zeros_gcc_ctz(count,x) \ - do { \ - ASSERT ((x) != 0); \ - (count) = __builtin_ctzll (x); \ - } while (0) -#else -#define count_trailing_zeros_gcc_ctz(count,x) \ - do { \ - ASSERT ((x) != 0); \ - (count) = __builtin_ctzl (x); \ - } while (0) -#endif - - -/* FIXME: The macros using external routines like __MPN(count_leading_zeros) - don't need to be under !NO_ASM */ -#if ! defined (NO_ASM) - -#if defined (__alpha) && W_TYPE_SIZE == 64 -/* Most alpha-based machines, except Cray systems. */ -#if defined (__GNUC__) -#if __GMP_GNUC_PREREQ (3,3) -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - UDItype __m0 = (m0), __m1 = (m1); \ - (ph) = __builtin_alpha_umulh (__m0, __m1); \ - (pl) = __m0 * __m1; \ - } while (0) -#else -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - UDItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("umulh %r1,%2,%0" \ - : "=r" (ph) \ - : "%rJ" (__m0), "rI" (__m1)); \ - (pl) = __m0 * __m1; \ - } while (0) -#endif -#else /* ! __GNUC__ */ -#include -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - UDItype __m0 = (m0), __m1 = (m1); \ - (ph) = __UMULH (__m0, __m1); \ - (pl) = __m0 * __m1; \ - } while (0) -#endif -#ifndef LONGLONG_STANDALONE -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { UWtype __di; \ - __di = __MPN(invert_limb) (d); \ - udiv_qrnnd_preinv (q, r, n1, n0, d, __di); \ - } while (0) -#define UDIV_PREINV_ALWAYS 1 -#define UDIV_NEEDS_NORMALIZATION 1 -#endif /* LONGLONG_STANDALONE */ - -/* clz_tab is required in all configurations, since mpn/alpha/cntlz.asm - always goes into libgmp.so, even when not actually used. */ -#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB - -#if defined (__GNUC__) && HAVE_HOST_CPU_alpha_CIX -#define count_leading_zeros(COUNT,X) \ - __asm__("ctlz %1,%0" : "=r"(COUNT) : "r"(X)) -#define count_trailing_zeros(COUNT,X) \ - __asm__("cttz %1,%0" : "=r"(COUNT) : "r"(X)) -#endif /* clz/ctz using cix */ - -#if ! defined (count_leading_zeros) \ - && defined (__GNUC__) && ! defined (LONGLONG_STANDALONE) -/* ALPHA_CMPBGE_0 gives "cmpbge $31,src,dst", ie. test src bytes == 0. - "$31" is written explicitly in the asm, since an "r" constraint won't - select reg 31. There seems no need to worry about "r31" syntax for cray, - since gcc itself (pre-release 3.4) emits just $31 in various places. */ -#define ALPHA_CMPBGE_0(dst, src) \ - do { asm ("cmpbge $31, %1, %0" : "=r" (dst) : "r" (src)); } while (0) -/* Zero bytes are turned into bits with cmpbge, a __clz_tab lookup counts - them, locating the highest non-zero byte. A second __clz_tab lookup - counts the leading zero bits in that byte, giving the result. */ -#define count_leading_zeros(count, x) \ - do { \ - UWtype __clz__b, __clz__c, __clz__x = (x); \ - ALPHA_CMPBGE_0 (__clz__b, __clz__x); /* zero bytes */ \ - __clz__b = __clz_tab [(__clz__b >> 1) ^ 0x7F]; /* 8 to 1 byte */ \ - __clz__b = __clz__b * 8 - 7; /* 57 to 1 shift */ \ - __clz__x >>= __clz__b; \ - __clz__c = __clz_tab [__clz__x]; /* 8 to 1 bit */ \ - __clz__b = 65 - __clz__b; \ - (count) = __clz__b - __clz__c; \ - } while (0) -#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB -#endif /* clz using cmpbge */ - -#if ! defined (count_leading_zeros) && ! defined (LONGLONG_STANDALONE) -#if HAVE_ATTRIBUTE_CONST -long __MPN(count_leading_zeros) (UDItype) __attribute__ ((const)); -#else -long __MPN(count_leading_zeros) (UDItype); -#endif -#define count_leading_zeros(count, x) \ - ((count) = __MPN(count_leading_zeros) (x)) -#endif /* clz using mpn */ -#endif /* __alpha */ - -#if defined (__AVR) && W_TYPE_SIZE == 8 -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - unsigned short __p = (unsigned short) (m0) * (m1); \ - (ph) = __p >> 8; \ - (pl) = __p; \ - } while (0) -#endif /* AVR */ - -#if defined (_CRAY) && W_TYPE_SIZE == 64 -#include -#define UDIV_PREINV_ALWAYS 1 -#define UDIV_NEEDS_NORMALIZATION 1 -long __MPN(count_leading_zeros) (UDItype); -#define count_leading_zeros(count, x) \ - ((count) = _leadz ((UWtype) (x))) -#if defined (_CRAYIEEE) /* I.e., Cray T90/ieee, T3D, and T3E */ -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - UDItype __m0 = (m0), __m1 = (m1); \ - (ph) = _int_mult_upper (__m0, __m1); \ - (pl) = __m0 * __m1; \ - } while (0) -#ifndef LONGLONG_STANDALONE -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { UWtype __di; \ - __di = __MPN(invert_limb) (d); \ - udiv_qrnnd_preinv (q, r, n1, n0, d, __di); \ - } while (0) -#endif /* LONGLONG_STANDALONE */ -#endif /* _CRAYIEEE */ -#endif /* _CRAY */ - -#if defined (__ia64) && W_TYPE_SIZE == 64 -/* This form encourages gcc (pre-release 3.4 at least) to emit predicated - "sub r=r,r" and "sub r=r,r,1", giving a 2 cycle latency. The generic - code using "al>= _c; \ - if (_x >= 1 << 4) \ - _x >>= 4, _c += 4; \ - if (_x >= 1 << 2) \ - _x >>= 2, _c += 2; \ - _c += _x >> 1; \ - (count) = W_TYPE_SIZE - 1 - _c; \ - } while (0) -/* similar to what gcc does for __builtin_ffs, but 0 based rather than 1 - based, and we don't need a special case for x==0 here */ -#define count_trailing_zeros(count, x) \ - do { \ - UWtype __ctz_x = (x); \ - __asm__ ("popcnt %0 = %1" \ - : "=r" (count) \ - : "r" ((__ctz_x-1) & ~__ctz_x)); \ - } while (0) -#endif -#if defined (__INTEL_COMPILER) -#include -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - UWtype __m0 = (m0), __m1 = (m1); \ - ph = _m64_xmahu (__m0, __m1, 0); \ - pl = __m0 * __m1; \ - } while (0) -#endif -#ifndef LONGLONG_STANDALONE -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { UWtype __di; \ - __di = __MPN(invert_limb) (d); \ - udiv_qrnnd_preinv (q, r, n1, n0, d, __di); \ - } while (0) -#define UDIV_PREINV_ALWAYS 1 -#define UDIV_NEEDS_NORMALIZATION 1 -#endif -#endif - - -#if defined (__GNUC__) - -/* We sometimes need to clobber "cc" with gcc2, but that would not be - understood by gcc1. Use cpp to avoid major code duplication. */ -#if __GNUC__ < 2 -#define __CLOBBER_CC -#define __AND_CLOBBER_CC -#else /* __GNUC__ >= 2 */ -#define __CLOBBER_CC : "cc" -#define __AND_CLOBBER_CC , "cc" -#endif /* __GNUC__ < 2 */ - -#if (defined (__a29k__) || defined (_AM29K)) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("add %1,%4,%5\n\taddc %0,%2,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "rI" (bh), "%r" (al), "rI" (bl)) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("sub %1,%4,%5\n\tsubc %0,%2,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "rI" (bh), "r" (al), "rI" (bl)) -#define umul_ppmm(xh, xl, m0, m1) \ - do { \ - USItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("multiplu %0,%1,%2" \ - : "=r" (xl) \ - : "r" (__m0), "r" (__m1)); \ - __asm__ ("multmu %0,%1,%2" \ - : "=r" (xh) \ - : "r" (__m0), "r" (__m1)); \ - } while (0) -#define udiv_qrnnd(q, r, n1, n0, d) \ - __asm__ ("dividu %0,%3,%4" \ - : "=r" (q), "=q" (r) \ - : "1" (n1), "r" (n0), "r" (d)) -#define count_leading_zeros(count, x) \ - __asm__ ("clz %0,%1" \ - : "=r" (count) \ - : "r" (x)) -#define COUNT_LEADING_ZEROS_0 32 -#endif /* __a29k__ */ - -#if defined (__arc__) -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("add.f\t%1, %4, %5\n\tadc\t%0, %2, %3" \ - : "=r" (sh), \ - "=&r" (sl) \ - : "r" ((USItype) (ah)), \ - "rICal" ((USItype) (bh)), \ - "%r" ((USItype) (al)), \ - "rICal" ((USItype) (bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("sub.f\t%1, %4, %5\n\tsbc\t%0, %2, %3" \ - : "=r" (sh), \ - "=&r" (sl) \ - : "r" ((USItype) (ah)), \ - "rICal" ((USItype) (bh)), \ - "r" ((USItype) (al)), \ - "rICal" ((USItype) (bl))) -#endif - -#if defined (__arm__) && (defined (__thumb2__) || !defined (__thumb__)) \ - && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (bl) && -(USItype)(bl) < (USItype)(bl)) \ - __asm__ ("subs\t%1, %4, %5\n\tadc\t%0, %2, %3" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "rI" (bh), \ - "%r" (al), "rI" (-(USItype)(bl)) __CLOBBER_CC); \ - else \ - __asm__ ("adds\t%1, %4, %5\n\tadc\t%0, %2, %3" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "rI" (bh), "%r" (al), "rI" (bl) __CLOBBER_CC); \ - } while (0) -/* FIXME: Extend the immediate range for the low word by using both ADDS and - SUBS, since they set carry in the same way. We need separate definitions - for thumb and non-thumb since thumb lacks RSC. */ -#if defined (__thumb__) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (ah) && __builtin_constant_p (bh) \ - && (ah) == (bh)) \ - __asm__ ("subs\t%1, %2, %3\n\tsbc\t%0, %0, %0" \ - : "=r" (sh), "=r" (sl) \ - : "r" (al), "rI" (bl) __CLOBBER_CC); \ - else if (__builtin_constant_p (al)) \ - __asm__ ("rsbs\t%1, %5, %4\n\tsbc\t%0, %2, %3" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "rI" (bh), "rI" (al), "r" (bl) __CLOBBER_CC); \ - else if (__builtin_constant_p (bl)) \ - __asm__ ("subs\t%1, %4, %5\n\tsbc\t%0, %2, %3" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "rI" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \ - else \ - __asm__ ("subs\t%1, %4, %5\n\tsbc\t%0, %2, %3" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "rI" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \ - } while (0) -#else -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (ah) && __builtin_constant_p (bh) \ - && (ah) == (bh)) \ - __asm__ ("subs\t%1, %2, %3\n\tsbc\t%0, %0, %0" \ - : "=r" (sh), "=r" (sl) \ - : "r" (al), "rI" (bl) __CLOBBER_CC); \ - else if (__builtin_constant_p (al)) \ - { \ - if (__builtin_constant_p (ah)) \ - __asm__ ("rsbs\t%1, %5, %4\n\trsc\t%0, %3, %2" \ - : "=r" (sh), "=&r" (sl) \ - : "rI" (ah), "r" (bh), "rI" (al), "r" (bl) __CLOBBER_CC); \ - else \ - __asm__ ("rsbs\t%1, %5, %4\n\tsbc\t%0, %2, %3" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "rI" (bh), "rI" (al), "r" (bl) __CLOBBER_CC); \ - } \ - else if (__builtin_constant_p (ah)) \ - { \ - if (__builtin_constant_p (bl)) \ - __asm__ ("subs\t%1, %4, %5\n\trsc\t%0, %3, %2" \ - : "=r" (sh), "=&r" (sl) \ - : "rI" (ah), "r" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \ - else \ - __asm__ ("rsbs\t%1, %5, %4\n\trsc\t%0, %3, %2" \ - : "=r" (sh), "=&r" (sl) \ - : "rI" (ah), "r" (bh), "rI" (al), "r" (bl) __CLOBBER_CC); \ - } \ - else if (__builtin_constant_p (bl)) \ - __asm__ ("subs\t%1, %4, %5\n\tsbc\t%0, %2, %3" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "rI" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \ - else \ - __asm__ ("subs\t%1, %4, %5\n\tsbc\t%0, %2, %3" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "rI" (bh), "r" (al), "rI" (bl) __CLOBBER_CC); \ - } while (0) -#endif -#if defined (__ARM_ARCH_2__) || defined (__ARM_ARCH_2A__) \ - || defined (__ARM_ARCH_3__) -#define umul_ppmm(xh, xl, a, b) \ - do { \ - register USItype __t0, __t1, __t2; \ - __asm__ ("%@ Inlined umul_ppmm\n" \ - " mov %2, %5, lsr #16\n" \ - " mov %0, %6, lsr #16\n" \ - " bic %3, %5, %2, lsl #16\n" \ - " bic %4, %6, %0, lsl #16\n" \ - " mul %1, %3, %4\n" \ - " mul %4, %2, %4\n" \ - " mul %3, %0, %3\n" \ - " mul %0, %2, %0\n" \ - " adds %3, %4, %3\n" \ - " addcs %0, %0, #65536\n" \ - " adds %1, %1, %3, lsl #16\n" \ - " adc %0, %0, %3, lsr #16" \ - : "=&r" ((USItype) (xh)), "=r" ((USItype) (xl)), \ - "=&r" (__t0), "=&r" (__t1), "=r" (__t2) \ - : "r" ((USItype) (a)), "r" ((USItype) (b)) __CLOBBER_CC); \ - } while (0) -#ifndef LONGLONG_STANDALONE -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { UWtype __r; \ - (q) = __MPN(udiv_qrnnd) (&__r, (n1), (n0), (d)); \ - (r) = __r; \ - } while (0) -extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype); -#endif /* LONGLONG_STANDALONE */ -#else /* ARMv4 or newer */ -#define umul_ppmm(xh, xl, a, b) \ - __asm__ ("umull %0,%1,%2,%3" : "=&r" (xl), "=&r" (xh) : "r" (a), "r" (b)) -#define smul_ppmm(xh, xl, a, b) \ - __asm__ ("smull %0,%1,%2,%3" : "=&r" (xl), "=&r" (xh) : "r" (a), "r" (b)) -#ifndef LONGLONG_STANDALONE -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { UWtype __di; \ - __di = __MPN(invert_limb) (d); \ - udiv_qrnnd_preinv (q, r, n1, n0, d, __di); \ - } while (0) -#define UDIV_PREINV_ALWAYS 1 -#define UDIV_NEEDS_NORMALIZATION 1 -#endif /* LONGLONG_STANDALONE */ -#endif /* defined(__ARM_ARCH_2__) ... */ -#define count_leading_zeros(count, x) count_leading_zeros_gcc_clz(count, x) -#define count_trailing_zeros(count, x) count_trailing_zeros_gcc_ctz(count, x) -#endif /* __arm__ */ - -#if defined (__aarch64__) && W_TYPE_SIZE == 64 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (bl) && ~(UDItype)(bl) <= (UDItype)(bl)) \ - __asm__ ("subs\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \ - : "=r" (sh), "=&r" (sl) \ - : "rZ" ((UDItype)(ah)), "rZ" ((UDItype)(bh)), \ - "%r" ((UDItype)(al)), "rI" (-(UDItype)(bl)) __CLOBBER_CC);\ - else \ - __asm__ ("adds\t%1, %x4, %5\n\tadc\t%0, %x2, %x3" \ - : "=r" (sh), "=&r" (sl) \ - : "rZ" ((UDItype)(ah)), "rZ" ((UDItype)(bh)), \ - "%r" ((UDItype)(al)), "rI" ((UDItype)(bl)) __CLOBBER_CC);\ - } while (0) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (bl) && ~(UDItype)(bl) <= (UDItype)(bl)) \ - __asm__ ("adds\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \ - : "=r,r" (sh), "=&r,&r" (sl) \ - : "rZ,rZ" ((UDItype)(ah)), "rZ,rZ" ((UDItype)(bh)), \ - "r,Z" ((UDItype)(al)), "rI,r" (-(UDItype)(bl)) __CLOBBER_CC);\ - else \ - __asm__ ("subs\t%1, %x4, %5\n\tsbc\t%0, %x2, %x3" \ - : "=r,r" (sh), "=&r,&r" (sl) \ - : "rZ,rZ" ((UDItype)(ah)), "rZ,rZ" ((UDItype)(bh)), \ - "r,Z" ((UDItype)(al)), "rI,r" ((UDItype)(bl)) __CLOBBER_CC);\ - } while(0); -#if __GMP_GNUC_PREREQ (4,9) -#define umul_ppmm(w1, w0, u, v) \ - do { \ - typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ - __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \ - w1 = __ll >> 64; \ - w0 = __ll; \ - } while (0) -#endif -#if !defined (umul_ppmm) -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - UDItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("umulh\t%0, %1, %2" : "=r" (ph) : "r" (__m0), "r" (__m1)); \ - (pl) = __m0 * __m1; \ - } while (0) -#endif -#define count_leading_zeros(count, x) count_leading_zeros_gcc_clz(count, x) -#define count_trailing_zeros(count, x) count_trailing_zeros_gcc_ctz(count, x) -#endif /* __aarch64__ */ - -#if defined (__clipper__) && W_TYPE_SIZE == 32 -#define umul_ppmm(w1, w0, u, v) \ - ({union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __x; \ - __asm__ ("mulwux %2,%0" \ - : "=r" (__x.__ll) \ - : "%0" ((USItype)(u)), "r" ((USItype)(v))); \ - (w1) = __x.__i.__h; (w0) = __x.__i.__l;}) -#define smul_ppmm(w1, w0, u, v) \ - ({union {DItype __ll; \ - struct {SItype __l, __h;} __i; \ - } __x; \ - __asm__ ("mulwx %2,%0" \ - : "=r" (__x.__ll) \ - : "%0" ((SItype)(u)), "r" ((SItype)(v))); \ - (w1) = __x.__i.__h; (w0) = __x.__i.__l;}) -#define __umulsidi3(u, v) \ - ({UDItype __w; \ - __asm__ ("mulwux %2,%0" \ - : "=r" (__w) : "%0" ((USItype)(u)), "r" ((USItype)(v))); \ - __w; }) -#endif /* __clipper__ */ - -/* Fujitsu vector computers. */ -#if defined (__uxp__) && W_TYPE_SIZE == 32 -#define umul_ppmm(ph, pl, u, v) \ - do { \ - union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x; \ - __asm__ ("mult.lu %1,%2,%0" : "=r" (__x.__ll) : "%r" (u), "rK" (v));\ - (ph) = __x.__i.__h; \ - (pl) = __x.__i.__l; \ - } while (0) -#define smul_ppmm(ph, pl, u, v) \ - do { \ - union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x; \ - __asm__ ("mult.l %1,%2,%0" : "=r" (__x.__ll) : "%r" (u), "rK" (v)); \ - (ph) = __x.__i.__h; \ - (pl) = __x.__i.__l; \ - } while (0) -#endif - -#if defined (__gmicro__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("add.w %5,%1\n\taddx %3,%0" \ - : "=g" (sh), "=&g" (sl) \ - : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \ - "%1" ((USItype)(al)), "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("sub.w %5,%1\n\tsubx %3,%0" \ - : "=g" (sh), "=&g" (sl) \ - : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \ - "1" ((USItype)(al)), "g" ((USItype)(bl))) -#define umul_ppmm(ph, pl, m0, m1) \ - __asm__ ("mulx %3,%0,%1" \ - : "=g" (ph), "=r" (pl) \ - : "%0" ((USItype)(m0)), "g" ((USItype)(m1))) -#define udiv_qrnnd(q, r, nh, nl, d) \ - __asm__ ("divx %4,%0,%1" \ - : "=g" (q), "=r" (r) \ - : "1" ((USItype)(nh)), "0" ((USItype)(nl)), "g" ((USItype)(d))) -#define count_leading_zeros(count, x) \ - __asm__ ("bsch/1 %1,%0" \ - : "=g" (count) : "g" ((USItype)(x)), "0" ((USItype)0)) -#endif - -#if defined (__hppa) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("add%I5 %5,%r4,%1\n\taddc %r2,%r3,%0" \ - : "=r" (sh), "=&r" (sl) \ - : "rM" (ah), "rM" (bh), "%rM" (al), "rI" (bl)) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("sub%I4 %4,%r5,%1\n\tsubb %r2,%r3,%0" \ - : "=r" (sh), "=&r" (sl) \ - : "rM" (ah), "rM" (bh), "rI" (al), "rM" (bl)) -#if defined (_PA_RISC1_1) -#define umul_ppmm(wh, wl, u, v) \ - do { \ - union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x; \ - __asm__ ("xmpyu %1,%2,%0" : "=*f" (__x.__ll) : "*f" (u), "*f" (v)); \ - (wh) = __x.__i.__h; \ - (wl) = __x.__i.__l; \ - } while (0) -#endif -#define count_leading_zeros(count, x) \ - do { \ - USItype __tmp; \ - __asm__ ( \ - "ldi 1,%0\n" \ -" extru,= %1,15,16,%%r0 ; Bits 31..16 zero?\n" \ -" extru,tr %1,15,16,%1 ; No. Shift down, skip add.\n" \ -" ldo 16(%0),%0 ; Yes. Perform add.\n" \ -" extru,= %1,23,8,%%r0 ; Bits 15..8 zero?\n" \ -" extru,tr %1,23,8,%1 ; No. Shift down, skip add.\n" \ -" ldo 8(%0),%0 ; Yes. Perform add.\n" \ -" extru,= %1,27,4,%%r0 ; Bits 7..4 zero?\n" \ -" extru,tr %1,27,4,%1 ; No. Shift down, skip add.\n" \ -" ldo 4(%0),%0 ; Yes. Perform add.\n" \ -" extru,= %1,29,2,%%r0 ; Bits 3..2 zero?\n" \ -" extru,tr %1,29,2,%1 ; No. Shift down, skip add.\n" \ -" ldo 2(%0),%0 ; Yes. Perform add.\n" \ -" extru %1,30,1,%1 ; Extract bit 1.\n" \ -" sub %0,%1,%0 ; Subtract it.\n" \ - : "=r" (count), "=r" (__tmp) : "1" (x)); \ - } while (0) -#endif /* hppa */ - -/* These macros are for ABI=2.0w. In ABI=2.0n they can't be used, since GCC - (3.2) puts longlong into two adjacent 32-bit registers. Presumably this - is just a case of no direct support for 2.0n but treating it like 1.0. */ -#if defined (__hppa) && W_TYPE_SIZE == 64 && ! defined (_LONG_LONG_LIMB) -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("add%I5 %5,%r4,%1\n\tadd,dc %r2,%r3,%0" \ - : "=r" (sh), "=&r" (sl) \ - : "rM" (ah), "rM" (bh), "%rM" (al), "rI" (bl)) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("sub%I4 %4,%r5,%1\n\tsub,db %r2,%r3,%0" \ - : "=r" (sh), "=&r" (sl) \ - : "rM" (ah), "rM" (bh), "rI" (al), "rM" (bl)) -#endif /* hppa */ - -#if (defined (__i370__) || defined (__s390__) || defined (__mvs__)) && W_TYPE_SIZE == 32 -#if defined (__zarch__) || defined (HAVE_HOST_CPU_s390_zarch) -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - do { \ -/* if (__builtin_constant_p (bl)) \ - __asm__ ("alfi\t%1,%o5\n\talcr\t%0,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "0" (ah), "r" (bh), "%1" (al), "n" (bl) __CLOBBER_CC);\ - else \ -*/ __asm__ ("alr\t%1,%5\n\talcr\t%0,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "0" (ah), "r" (bh), "%1" (al), "r" (bl)__CLOBBER_CC); \ - } while (0) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - do { \ -/* if (__builtin_constant_p (bl)) \ - __asm__ ("slfi\t%1,%o5\n\tslbr\t%0,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "0" (ah), "r" (bh), "1" (al), "n" (bl) __CLOBBER_CC); \ - else \ -*/ __asm__ ("slr\t%1,%5\n\tslbr\t%0,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "0" (ah), "r" (bh), "1" (al), "r" (bl) __CLOBBER_CC); \ - } while (0) -#if __GMP_GNUC_PREREQ (4,5) -#define umul_ppmm(xh, xl, m0, m1) \ - do { \ - union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x; \ - __x.__ll = (UDItype) (m0) * (UDItype) (m1); \ - (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ - } while (0) -#else -#if 0 -/* FIXME: this fails if gcc knows about the 64-bit registers. Use only - with a new enough processor pretending we have 32-bit registers. */ -#define umul_ppmm(xh, xl, m0, m1) \ - do { \ - union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x; \ - __asm__ ("mlr\t%0,%2" \ - : "=r" (__x.__ll) \ - : "%0" (m0), "r" (m1)); \ - (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ - } while (0) -#else -#define umul_ppmm(xh, xl, m0, m1) \ - do { \ - /* When we have 64-bit regs and gcc is aware of that, we cannot simply use - DImode for the product, since that would be allocated to a single 64-bit - register, whereas mlr uses the low 32-bits of an even-odd register pair. - */ \ - register USItype __r0 __asm__ ("0"); \ - register USItype __r1 __asm__ ("1") = (m0); \ - __asm__ ("mlr\t%0,%3" \ - : "=r" (__r0), "=r" (__r1) \ - : "r" (__r1), "r" (m1)); \ - (xh) = __r0; (xl) = __r1; \ - } while (0) -#endif /* if 0 */ -#endif -#if 0 -/* FIXME: this fails if gcc knows about the 64-bit registers. Use only - with a new enough processor pretending we have 32-bit registers. */ -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { \ - union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x; \ - __x.__i.__h = n1; __x.__i.__l = n0; \ - __asm__ ("dlr\t%0,%2" \ - : "=r" (__x.__ll) \ - : "0" (__x.__ll), "r" (d)); \ - (q) = __x.__i.__l; (r) = __x.__i.__h; \ - } while (0) -#else -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { \ - register USItype __r0 __asm__ ("0") = (n1); \ - register USItype __r1 __asm__ ("1") = (n0); \ - __asm__ ("dlr\t%0,%4" \ - : "=r" (__r0), "=r" (__r1) \ - : "r" (__r0), "r" (__r1), "r" (d)); \ - (q) = __r1; (r) = __r0; \ - } while (0) -#endif /* if 0 */ -#else /* if __zarch__ */ -/* FIXME: this fails if gcc knows about the 64-bit registers. */ -#define smul_ppmm(xh, xl, m0, m1) \ - do { \ - union {DItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x; \ - __asm__ ("mr\t%0,%2" \ - : "=r" (__x.__ll) \ - : "%0" (m0), "r" (m1)); \ - (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ - } while (0) -/* FIXME: this fails if gcc knows about the 64-bit registers. */ -#define sdiv_qrnnd(q, r, n1, n0, d) \ - do { \ - union {DItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x; \ - __x.__i.__h = n1; __x.__i.__l = n0; \ - __asm__ ("dr\t%0,%2" \ - : "=r" (__x.__ll) \ - : "0" (__x.__ll), "r" (d)); \ - (q) = __x.__i.__l; (r) = __x.__i.__h; \ - } while (0) -#endif /* if __zarch__ */ -#endif - -#if defined (__s390x__) && W_TYPE_SIZE == 64 -/* We need to cast operands with register constraints, otherwise their types - will be assumed to be SImode by gcc. For these machines, such operations - will insert a value into the low 32 bits, and leave the high 32 bits with - garbage. */ -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - do { \ - __asm__ ("algr\t%1,%5\n\talcgr\t%0,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "0" ((UDItype)(ah)), "r" ((UDItype)(bh)), \ - "%1" ((UDItype)(al)), "r" ((UDItype)(bl)) __CLOBBER_CC); \ - } while (0) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - do { \ - __asm__ ("slgr\t%1,%5\n\tslbgr\t%0,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "0" ((UDItype)(ah)), "r" ((UDItype)(bh)), \ - "1" ((UDItype)(al)), "r" ((UDItype)(bl)) __CLOBBER_CC); \ - } while (0) -#define umul_ppmm(xh, xl, m0, m1) \ - do { \ - union {unsigned int __attribute__ ((mode(TI))) __ll; \ - struct {UDItype __h, __l;} __i; \ - } __x; \ - __asm__ ("mlgr\t%0,%2" \ - : "=r" (__x.__ll) \ - : "%0" ((UDItype)(m0)), "r" ((UDItype)(m1))); \ - (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ - } while (0) -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { \ - union {unsigned int __attribute__ ((mode(TI))) __ll; \ - struct {UDItype __h, __l;} __i; \ - } __x; \ - __x.__i.__h = n1; __x.__i.__l = n0; \ - __asm__ ("dlgr\t%0,%2" \ - : "=r" (__x.__ll) \ - : "0" (__x.__ll), "r" ((UDItype)(d))); \ - (q) = __x.__i.__l; (r) = __x.__i.__h; \ - } while (0) -#if 0 /* FIXME: Enable for z10 (?) */ -#define count_leading_zeros(cnt, x) \ - do { \ - union {unsigned int __attribute__ ((mode(TI))) __ll; \ - struct {UDItype __h, __l;} __i; \ - } __clr_cnt; \ - __asm__ ("flogr\t%0,%1" \ - : "=r" (__clr_cnt.__ll) \ - : "r" (x) __CLOBBER_CC); \ - (cnt) = __clr_cnt.__i.__h; \ - } while (0) -#endif -#endif - -/* On x86 and x86_64, every asm implicitly clobbers "flags" and "fpsr", - so we don't need __CLOBBER_CC. */ -#if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("addl %5,%k1\n\tadcl %3,%k0" \ - : "=r" (sh), "=&r" (sl) \ - : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \ - "%1" ((USItype)(al)), "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subl %5,%k1\n\tsbbl %3,%k0" \ - : "=r" (sh), "=&r" (sl) \ - : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \ - "1" ((USItype)(al)), "g" ((USItype)(bl))) -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("mull %3" \ - : "=a" (w0), "=d" (w1) \ - : "%0" ((USItype)(u)), "rm" ((USItype)(v))) -#define udiv_qrnnd(q, r, n1, n0, dx) /* d renamed to dx avoiding "=d" */\ - __asm__ ("divl %4" /* stringification in K&R C */ \ - : "=a" (q), "=d" (r) \ - : "0" ((USItype)(n0)), "1" ((USItype)(n1)), "rm" ((USItype)(dx))) - -#if HAVE_HOST_CPU_i586 || HAVE_HOST_CPU_pentium || HAVE_HOST_CPU_pentiummmx -/* Pentium bsrl takes between 10 and 72 cycles depending where the most - significant 1 bit is, hence the use of the following alternatives. bsfl - is slow too, between 18 and 42 depending where the least significant 1 - bit is, so let the generic count_trailing_zeros below make use of the - count_leading_zeros here too. */ - -#if HAVE_HOST_CPU_pentiummmx && ! defined (LONGLONG_STANDALONE) -/* The following should be a fixed 14 or 15 cycles, but possibly plus an L1 - cache miss reading from __clz_tab. For P55 it's favoured over the float - below so as to avoid mixing MMX and x87, since the penalty for switching - between the two is about 100 cycles. - - The asm block sets __shift to -3 if the high 24 bits are clear, -2 for - 16, -1 for 8, or 0 otherwise. This could be written equivalently as - follows, but as of gcc 2.95.2 it results in conditional jumps. - - __shift = -(__n < 0x1000000); - __shift -= (__n < 0x10000); - __shift -= (__n < 0x100); - - The middle two sbbl and cmpl's pair, and with luck something gcc - generates might pair with the first cmpl and the last sbbl. The "32+1" - constant could be folded into __clz_tab[], but it doesn't seem worth - making a different table just for that. */ - -#define count_leading_zeros(c,n) \ - do { \ - USItype __n = (n); \ - USItype __shift; \ - __asm__ ("cmpl $0x1000000, %1\n" \ - "sbbl %0, %0\n" \ - "cmpl $0x10000, %1\n" \ - "sbbl $0, %0\n" \ - "cmpl $0x100, %1\n" \ - "sbbl $0, %0\n" \ - : "=&r" (__shift) : "r" (__n)); \ - __shift = __shift*8 + 24 + 1; \ - (c) = 32 + 1 - __shift - __clz_tab[__n >> __shift]; \ - } while (0) -#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB -#define COUNT_LEADING_ZEROS_0 31 /* n==0 indistinguishable from n==1 */ - -#else /* ! pentiummmx || LONGLONG_STANDALONE */ -/* The following should be a fixed 14 cycles or so. Some scheduling - opportunities should be available between the float load/store too. This - sort of code is used in gcc 3 for __builtin_ffs (with "n&-n") and is - apparently suggested by the Intel optimizing manual (don't know exactly - where). gcc 2.95 or up will be best for this, so the "double" is - correctly aligned on the stack. */ -#define count_leading_zeros(c,n) \ - do { \ - union { \ - double d; \ - unsigned a[2]; \ - } __u; \ - __u.d = (UWtype) (n); \ - (c) = 0x3FF + 31 - (__u.a[1] >> 20); \ - } while (0) -#define COUNT_LEADING_ZEROS_0 (0x3FF + 31) -#endif /* pentiummx */ - -#else /* ! pentium */ - -#if __GMP_GNUC_PREREQ (3,4) /* using bsrl */ -#define count_leading_zeros(count,x) count_leading_zeros_gcc_clz(count,x) -#endif /* gcc clz */ - -/* On P6, gcc prior to 3.0 generates a partial register stall for - __cbtmp^31, due to using "xorb $31" instead of "xorl $31", the former - being 1 code byte smaller. "31-__cbtmp" is a workaround, probably at the - cost of one extra instruction. Do this for "i386" too, since that means - generic x86. */ -#if ! defined (count_leading_zeros) && __GNUC__ < 3 \ - && (HAVE_HOST_CPU_i386 \ - || HAVE_HOST_CPU_i686 \ - || HAVE_HOST_CPU_pentiumpro \ - || HAVE_HOST_CPU_pentium2 \ - || HAVE_HOST_CPU_pentium3) -#define count_leading_zeros(count, x) \ - do { \ - USItype __cbtmp; \ - ASSERT ((x) != 0); \ - __asm__ ("bsrl %1,%0" : "=r" (__cbtmp) : "rm" ((USItype)(x))); \ - (count) = 31 - __cbtmp; \ - } while (0) -#endif /* gcc<3 asm bsrl */ - -#ifndef count_leading_zeros -#define count_leading_zeros(count, x) \ - do { \ - USItype __cbtmp; \ - ASSERT ((x) != 0); \ - __asm__ ("bsrl %1,%0" : "=r" (__cbtmp) : "rm" ((USItype)(x))); \ - (count) = __cbtmp ^ 31; \ - } while (0) -#endif /* asm bsrl */ - -#if __GMP_GNUC_PREREQ (3,4) /* using bsfl */ -#define count_trailing_zeros(count,x) count_trailing_zeros_gcc_ctz(count,x) -#endif /* gcc ctz */ - -#ifndef count_trailing_zeros -#define count_trailing_zeros(count, x) \ - do { \ - ASSERT ((x) != 0); \ - __asm__ ("bsfl %1,%k0" : "=r" (count) : "rm" ((USItype)(x))); \ - } while (0) -#endif /* asm bsfl */ - -#endif /* ! pentium */ - -#endif /* 80x86 */ - -#if defined (__amd64__) && W_TYPE_SIZE == 64 - -#ifndef RUNTIMECPUID -#define RUNTIMECPUID - -extern int bCheckedBMI; -extern int bBMI1; -extern int bBMI2; - -inline void hasBMI() -{ - if(bCheckedBMI) - return; - - bCheckedBMI = 1; - int info[4] = {0}; -#if defined(_MSC_VER) - __cpuid(info, 0x7); -#elif defined(__GNUC__) || defined(__clang__) -#if defined(ARCH_X86) && defined(__PIC__) - __asm__ __volatile__ ( - "xchg{l} {%%}ebx, %k1;" - "cpuid;" - "xchg{l} {%%}ebx, %k1;" - : "=a"(info[0]), "=&r"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(0x7), "c"(0) - ); -#else - __asm__ __volatile__ ( - "cpuid" : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(0x7), "c"(0) - ); -#endif -#endif - bBMI1 = ((info[1] & (1 << 3)) != 0); - bBMI2 = ((info[1] & (1 << 8)) != 0); -} - -inline int hasBMI1() -{ - hasBMI(); - return bBMI1; -} - -inline int hasBMI2() -{ - hasBMI(); - return bBMI2; -} - -extern int bCheckedLZCNT; -extern int bLZCNT; - -inline int hasLZCNT() -{ - if(bCheckedLZCNT) - return bLZCNT; - - bCheckedLZCNT = 1; - int info[4] = {0}; - #if defined(_MSC_VER) - __cpuid(info, 0x80000001); - #elif defined(__GNUC__) || defined(__clang__) - #if defined(ARCH_X86) && defined(__PIC__) - __asm__ __volatile__ ( - "xchg{l} {%%}ebx, %k1;" - "cpuid;" - "xchg{l} {%%}ebx, %k1;" - : "=a"(info[0]), "=&r"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(0x80000001), "c"(0) - ); - #else - __asm__ __volatile__ ( - "cpuid" : "=a"(info[0]), "=b"(info[1]), "=c"(info[2]), "=d"(info[3]) : "a"(0x80000001), "c"(0) - ); - #endif - #endif - - bLZCNT = ((info[2] & (1 << 5)) != 0); - return bLZCNT; -} - -#endif // RUNTIMECPUID - -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("addq %5,%q1\n\tadcq %3,%q0" \ - : "=r" (sh), "=&r" (sl) \ - : "0" ((UDItype)(ah)), "rme" ((UDItype)(bh)), \ - "%1" ((UDItype)(al)), "rme" ((UDItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subq %5,%q1\n\tsbbq %3,%q0" \ - : "=r" (sh), "=&r" (sl) \ - : "0" ((UDItype)(ah)), "rme" ((UDItype)(bh)), \ - "1" ((UDItype)(al)), "rme" ((UDItype)(bl))) -#define umul_ppmm(w1, w0, u, v) \ - if(hasBMI2()) { \ - __asm__ ("mulx\t%3, %q0, %q1" \ - : "=r" (w0), "=r" (w1) \ - : "%d" ((UDItype)(u)), "rm" ((UDItype)(v))); \ - } else { \ - __asm__ ("mulq\t%3" \ - : "=a" (w0), "=d" (w1) \ - : "%0" ((UDItype)(u)), "rm" ((UDItype)(v))); \ - } -#define udiv_qrnnd(q, r, n1, n0, dx) /* d renamed to dx avoiding "=d" */\ - __asm__ ("divq %4" /* stringification in K&R C */ \ - : "=a" (q), "=d" (r) \ - : "0" ((UDItype)(n0)), "1" ((UDItype)(n1)), "rm" ((UDItype)(dx))) - -#define count_leading_zeros(count, x) \ - if(hasLZCNT()) { \ - do { \ - /* This is lzcnt, spelled for older assemblers. Destination and */ \ - /* source must be a 64-bit registers, hence cast and %q. */ \ - __asm__ ("rep;bsr\t%1, %q0" : "=r" (count) : "rm" ((UDItype)(x))); \ - } while (0); \ - } else { \ - do { \ - UDItype __cbtmp; \ - ASSERT ((x) != 0); \ - __asm__ ("bsr\t%1,%0" : "=r" (__cbtmp) : "rm" ((UDItype)(x))); \ - (count) = __cbtmp ^ 63; \ - } while (0); \ - } -#define COUNT_LEADING_ZEROS_0 64 - -#define count_trailing_zeros(count, x) \ - if(hasBMI1()) { \ - do { \ - /* This is tzcnt, spelled for older assemblers. Destination and */ \ - /* source must be a 64-bit registers, hence cast and %q. */ \ - __asm__ ("rep;bsf\t%1, %q0" : "=r" (count) : "rm" ((UDItype)(x))); \ - } while (0); \ - } else { \ - do { \ - ASSERT ((x) != 0); \ - __asm__ ("bsf\t%1, %q0" : "=r" (count) : "rm" ((UDItype)(x))); \ - } while (0); \ - } -#define COUNT_TRAILING_ZEROS_0 64 -#endif /* __amd64__ */ - -#if defined (__i860__) && W_TYPE_SIZE == 32 -#define rshift_rhlc(r,h,l,c) \ - __asm__ ("shr %3,r0,r0\;shrd %1,%2,%0" \ - "=r" (r) : "r" (h), "r" (l), "rn" (c)) -#endif /* i860 */ - -#if defined (__i960__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("cmpo 1,0\;addc %5,%4,%1\;addc %3,%2,%0" \ - : "=r" (sh), "=&r" (sl) \ - : "dI" (ah), "dI" (bh), "%dI" (al), "dI" (bl)) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("cmpo 0,0\;subc %5,%4,%1\;subc %3,%2,%0" \ - : "=r" (sh), "=&r" (sl) \ - : "dI" (ah), "dI" (bh), "dI" (al), "dI" (bl)) -#define umul_ppmm(w1, w0, u, v) \ - ({union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __x; \ - __asm__ ("emul %2,%1,%0" \ - : "=d" (__x.__ll) : "%dI" (u), "dI" (v)); \ - (w1) = __x.__i.__h; (w0) = __x.__i.__l;}) -#define __umulsidi3(u, v) \ - ({UDItype __w; \ - __asm__ ("emul %2,%1,%0" : "=d" (__w) : "%dI" (u), "dI" (v)); \ - __w; }) -#define udiv_qrnnd(q, r, nh, nl, d) \ - do { \ - union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __nn; \ - __nn.__i.__h = (nh); __nn.__i.__l = (nl); \ - __asm__ ("ediv %d,%n,%0" \ - : "=d" (__rq.__ll) : "dI" (__nn.__ll), "dI" (d)); \ - (r) = __rq.__i.__l; (q) = __rq.__i.__h; \ - } while (0) -#define count_leading_zeros(count, x) \ - do { \ - USItype __cbtmp; \ - __asm__ ("scanbit %1,%0" : "=r" (__cbtmp) : "r" (x)); \ - (count) = __cbtmp ^ 31; \ - } while (0) -#define COUNT_LEADING_ZEROS_0 (-32) /* sic */ -#if defined (__i960mx) /* what is the proper symbol to test??? */ -#define rshift_rhlc(r,h,l,c) \ - do { \ - union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __nn; \ - __nn.__i.__h = (h); __nn.__i.__l = (l); \ - __asm__ ("shre %2,%1,%0" : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \ - } -#endif /* i960mx */ -#endif /* i960 */ - -#if (defined (__mc68000__) || defined (__mc68020__) || defined(mc68020) \ - || defined (__m68k__) || defined (__mc5200__) || defined (__mc5206e__) \ - || defined (__mc5307__)) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("add%.l %5,%1\n\taddx%.l %3,%0" \ - : "=d" (sh), "=&d" (sl) \ - : "0" ((USItype)(ah)), "d" ((USItype)(bh)), \ - "%1" ((USItype)(al)), "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("sub%.l %5,%1\n\tsubx%.l %3,%0" \ - : "=d" (sh), "=&d" (sl) \ - : "0" ((USItype)(ah)), "d" ((USItype)(bh)), \ - "1" ((USItype)(al)), "g" ((USItype)(bl))) -/* The '020, '030, '040 and CPU32 have 32x32->64 and 64/32->32q-32r. */ -#if defined (__mc68020__) || defined(mc68020) \ - || defined (__mc68030__) || defined (mc68030) \ - || defined (__mc68040__) || defined (mc68040) \ - || defined (__mcpu32__) || defined (mcpu32) \ - || defined (__NeXT__) -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("mulu%.l %3,%1:%0" \ - : "=d" (w0), "=d" (w1) \ - : "%0" ((USItype)(u)), "dmi" ((USItype)(v))) -#define udiv_qrnnd(q, r, n1, n0, d) \ - __asm__ ("divu%.l %4,%1:%0" \ - : "=d" (q), "=d" (r) \ - : "0" ((USItype)(n0)), "1" ((USItype)(n1)), "dmi" ((USItype)(d))) -#define sdiv_qrnnd(q, r, n1, n0, d) \ - __asm__ ("divs%.l %4,%1:%0" \ - : "=d" (q), "=d" (r) \ - : "0" ((USItype)(n0)), "1" ((USItype)(n1)), "dmi" ((USItype)(d))) -#else /* for other 68k family members use 16x16->32 multiplication */ -#define umul_ppmm(xh, xl, a, b) \ - do { USItype __umul_tmp1, __umul_tmp2; \ - __asm__ ("| Inlined umul_ppmm\n" \ -" move%.l %5,%3\n" \ -" move%.l %2,%0\n" \ -" move%.w %3,%1\n" \ -" swap %3\n" \ -" swap %0\n" \ -" mulu%.w %2,%1\n" \ -" mulu%.w %3,%0\n" \ -" mulu%.w %2,%3\n" \ -" swap %2\n" \ -" mulu%.w %5,%2\n" \ -" add%.l %3,%2\n" \ -" jcc 1f\n" \ -" add%.l %#0x10000,%0\n" \ -"1: move%.l %2,%3\n" \ -" clr%.w %2\n" \ -" swap %2\n" \ -" swap %3\n" \ -" clr%.w %3\n" \ -" add%.l %3,%1\n" \ -" addx%.l %2,%0\n" \ -" | End inlined umul_ppmm" \ - : "=&d" (xh), "=&d" (xl), \ - "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \ - : "%2" ((USItype)(a)), "d" ((USItype)(b))); \ - } while (0) -#endif /* not mc68020 */ -/* The '020, '030, '040 and '060 have bitfield insns. - GCC 3.4 defines __mc68020__ when in CPU32 mode, check for __mcpu32__ to - exclude bfffo on that chip (bitfield insns not available). */ -#if (defined (__mc68020__) || defined (mc68020) \ - || defined (__mc68030__) || defined (mc68030) \ - || defined (__mc68040__) || defined (mc68040) \ - || defined (__mc68060__) || defined (mc68060) \ - || defined (__NeXT__)) \ - && ! defined (__mcpu32__) -#define count_leading_zeros(count, x) \ - __asm__ ("bfffo %1{%b2:%b2},%0" \ - : "=d" (count) \ - : "od" ((USItype) (x)), "n" (0)) -#define COUNT_LEADING_ZEROS_0 32 -#endif -#endif /* mc68000 */ - -#if defined (__m88000__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("addu.co %1,%r4,%r5\n\taddu.ci %0,%r2,%r3" \ - : "=r" (sh), "=&r" (sl) \ - : "rJ" (ah), "rJ" (bh), "%rJ" (al), "rJ" (bl)) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subu.co %1,%r4,%r5\n\tsubu.ci %0,%r2,%r3" \ - : "=r" (sh), "=&r" (sl) \ - : "rJ" (ah), "rJ" (bh), "rJ" (al), "rJ" (bl)) -#define count_leading_zeros(count, x) \ - do { \ - USItype __cbtmp; \ - __asm__ ("ff1 %0,%1" : "=r" (__cbtmp) : "r" (x)); \ - (count) = __cbtmp ^ 31; \ - } while (0) -#define COUNT_LEADING_ZEROS_0 63 /* sic */ -#if defined (__m88110__) -#define umul_ppmm(wh, wl, u, v) \ - do { \ - union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x; \ - __asm__ ("mulu.d %0,%1,%2" : "=r" (__x.__ll) : "r" (u), "r" (v)); \ - (wh) = __x.__i.__h; \ - (wl) = __x.__i.__l; \ - } while (0) -#define udiv_qrnnd(q, r, n1, n0, d) \ - ({union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x, __q; \ - __x.__i.__h = (n1); __x.__i.__l = (n0); \ - __asm__ ("divu.d %0,%1,%2" \ - : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \ - (r) = (n0) - __q.__l * (d); (q) = __q.__l; }) -#endif /* __m88110__ */ -#endif /* __m88000__ */ - -#if defined (__mips) && W_TYPE_SIZE == 32 -#if __GMP_GNUC_PREREQ (4,4) -#define umul_ppmm(w1, w0, u, v) \ - do { \ - UDItype __ll = (UDItype)(u) * (v); \ - w1 = __ll >> 32; \ - w0 = __ll; \ - } while (0) -#endif -#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7) && !defined (__clang__) -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("multu %2,%3" : "=l" (w0), "=h" (w1) : "d" (u), "d" (v)) -#endif -#if !defined (umul_ppmm) -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("multu %2,%3\n\tmflo %0\n\tmfhi %1" \ - : "=d" (w0), "=d" (w1) : "d" (u), "d" (v)) -#endif -#endif /* __mips */ - -#if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64 -#if defined (_MIPS_ARCH_MIPS64R6) -#define umul_ppmm(w1, w0, u, v) \ - do { \ - UDItype __m0 = (u), __m1 = (v); \ - (w0) = __m0 * __m1; \ - __asm__ ("dmuhu\t%0, %1, %2" : "=d" (w1) : "d" (__m0), "d" (__m1)); \ - } while (0) -#endif -#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (4,4) -#define umul_ppmm(w1, w0, u, v) \ - do { \ - typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ - __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \ - w1 = __ll >> 64; \ - w0 = __ll; \ - } while (0) -#endif -#if !defined (umul_ppmm) && __GMP_GNUC_PREREQ (2,7) && !defined (__clang__) -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("dmultu %2,%3" \ - : "=l" (w0), "=h" (w1) \ - : "d" ((UDItype)(u)), "d" ((UDItype)(v))) -#endif -#if !defined (umul_ppmm) -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("dmultu %2,%3\n\tmflo %0\n\tmfhi %1" \ - : "=d" (w0), "=d" (w1) \ - : "d" ((UDItype)(u)), "d" ((UDItype)(v))) -#endif -#endif /* __mips */ - -#if defined (__mmix__) && W_TYPE_SIZE == 64 -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("MULU %0,%2,%3" : "=r" (w0), "=z" (w1) : "r" (u), "r" (v)) -#endif - -#if defined (__ns32000__) && W_TYPE_SIZE == 32 -#define umul_ppmm(w1, w0, u, v) \ - ({union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __x; \ - __asm__ ("meid %2,%0" \ - : "=g" (__x.__ll) \ - : "%0" ((USItype)(u)), "g" ((USItype)(v))); \ - (w1) = __x.__i.__h; (w0) = __x.__i.__l;}) -#define __umulsidi3(u, v) \ - ({UDItype __w; \ - __asm__ ("meid %2,%0" \ - : "=g" (__w) \ - : "%0" ((USItype)(u)), "g" ((USItype)(v))); \ - __w; }) -#define udiv_qrnnd(q, r, n1, n0, d) \ - ({union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __x; \ - __x.__i.__h = (n1); __x.__i.__l = (n0); \ - __asm__ ("deid %2,%0" \ - : "=g" (__x.__ll) \ - : "0" (__x.__ll), "g" ((USItype)(d))); \ - (r) = __x.__i.__l; (q) = __x.__i.__h; }) -#define count_trailing_zeros(count,x) \ - do { \ - __asm__ ("ffsd %2,%0" \ - : "=r" (count) \ - : "0" ((USItype) 0), "r" ((USItype) (x))); \ - } while (0) -#endif /* __ns32000__ */ - -/* In the past we had a block of various #defines tested - _ARCH_PPC - AIX - _ARCH_PWR - AIX - __powerpc__ - gcc - __POWERPC__ - BEOS - __ppc__ - Darwin - PPC - old gcc, GNU/Linux, SysV - The plain PPC test was not good for vxWorks, since PPC is defined on all - CPUs there (eg. m68k too), as a constant one is expected to compare - CPU_FAMILY against. - - At any rate, this was pretty unattractive and a bit fragile. The use of - HAVE_HOST_CPU_FAMILY is designed to cut through it all and be sure of - getting the desired effect. - - ENHANCE-ME: We should test _IBMR2 here when we add assembly support for - the system vendor compilers. (Is that vendor compilers with inline asm, - or what?) */ - -#if (HAVE_HOST_CPU_FAMILY_power || HAVE_HOST_CPU_FAMILY_powerpc) \ - && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (bh) && (bh) == 0) \ - __asm__ ("add%I4c %1,%3,%4\n\taddze %0,%2" \ - : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl) \ - __CLOBBER_CC); \ - else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ - __asm__ ("add%I4c %1,%3,%4\n\taddme %0,%2" \ - : "=r" (sh), "=&r" (sl) : "r" (ah), "%r" (al), "rI" (bl) \ - __CLOBBER_CC); \ - else \ - __asm__ ("add%I5c %1,%4,%5\n\tadde %0,%2,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "r" (bh), "%r" (al), "rI" (bl) \ - __CLOBBER_CC); \ - } while (0) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (ah) && (ah) == 0) \ - __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2" \ - : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl) \ - __CLOBBER_CC); \ - else if (__builtin_constant_p (ah) && (ah) == ~(USItype) 0) \ - __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2" \ - : "=r" (sh), "=&r" (sl) : "r" (bh), "rI" (al), "r" (bl) \ - __CLOBBER_CC); \ - else if (__builtin_constant_p (bh) && (bh) == 0) \ - __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2" \ - : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl) \ - __CLOBBER_CC); \ - else if (__builtin_constant_p (bh) && (bh) == ~(USItype) 0) \ - __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2" \ - : "=r" (sh), "=&r" (sl) : "r" (ah), "rI" (al), "r" (bl) \ - __CLOBBER_CC); \ - else \ - __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" (ah), "r" (bh), "rI" (al), "r" (bl) \ - __CLOBBER_CC); \ - } while (0) -#define count_leading_zeros(count, x) \ - __asm__ ("cntlzw %0,%1" : "=r" (count) : "r" (x)) -#define COUNT_LEADING_ZEROS_0 32 -#if HAVE_HOST_CPU_FAMILY_powerpc -#if __GMP_GNUC_PREREQ (4,4) -#define umul_ppmm(w1, w0, u, v) \ - do { \ - UDItype __ll = (UDItype)(u) * (v); \ - w1 = __ll >> 32; \ - w0 = __ll; \ - } while (0) -#endif -#if !defined (umul_ppmm) -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - USItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("mulhwu %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ - (pl) = __m0 * __m1; \ - } while (0) -#endif -#define smul_ppmm(ph, pl, m0, m1) \ - do { \ - SItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("mulhw %0,%1,%2" : "=r" (ph) : "%r" (m0), "r" (m1)); \ - (pl) = __m0 * __m1; \ - } while (0) -#else -#define smul_ppmm(xh, xl, m0, m1) \ - __asm__ ("mul %0,%2,%3" : "=r" (xh), "=q" (xl) : "r" (m0), "r" (m1)) -#define sdiv_qrnnd(q, r, nh, nl, d) \ - __asm__ ("div %0,%2,%4" : "=r" (q), "=q" (r) : "r" (nh), "1" (nl), "r" (d)) -#endif -#endif /* 32-bit POWER architecture variants. */ - -/* We should test _IBMR2 here when we add assembly support for the system - vendor compilers. */ -#if HAVE_HOST_CPU_FAMILY_powerpc && W_TYPE_SIZE == 64 -#if !defined (_LONG_LONG_LIMB) -/* _LONG_LONG_LIMB is ABI=mode32 where adde operates on 32-bit values. So - use adde etc only when not _LONG_LONG_LIMB. */ -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (bh) && (bh) == 0) \ - __asm__ ("add%I4c %1,%3,%4\n\taddze %0,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(ah)), \ - "%r" ((UDItype)(al)), "rI" ((UDItype)(bl)) \ - __CLOBBER_CC); \ - else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ - __asm__ ("add%I4c %1,%3,%4\n\taddme %0,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(ah)), \ - "%r" ((UDItype)(al)), "rI" ((UDItype)(bl)) \ - __CLOBBER_CC); \ - else \ - __asm__ ("add%I5c %1,%4,%5\n\tadde %0,%2,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(ah)), "r" ((UDItype)(bh)), \ - "%r" ((UDItype)(al)), "rI" ((UDItype)(bl)) \ - __CLOBBER_CC); \ - } while (0) -/* We use "*rI" for the constant operand here, since with just "I", gcc barfs. - This might seem strange, but gcc folds away the dead code late. */ -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - do { \ - if (__builtin_constant_p (bl) \ - && (bl) > -0x8000 && (bl) <= 0x8000 && (bl) != 0) { \ - if (__builtin_constant_p (ah) && (ah) == 0) \ - __asm__ ("addic %1,%3,%4\n\tsubfze %0,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(bh)), \ - "r" ((UDItype)(al)), "*rI" (-((UDItype)(bl))) \ - __CLOBBER_CC); \ - else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ - __asm__ ("addic %1,%3,%4\n\tsubfme %0,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(bh)), \ - "r" ((UDItype)(al)), "*rI" (-((UDItype)(bl))) \ - __CLOBBER_CC); \ - else if (__builtin_constant_p (bh) && (bh) == 0) \ - __asm__ ("addic %1,%3,%4\n\taddme %0,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(ah)), \ - "r" ((UDItype)(al)), "*rI" (-((UDItype)(bl))) \ - __CLOBBER_CC); \ - else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ - __asm__ ("addic %1,%3,%4\n\taddze %0,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(ah)), \ - "r" ((UDItype)(al)), "*rI" (-((UDItype)(bl))) \ - __CLOBBER_CC); \ - else \ - __asm__ ("addic %1,%4,%5\n\tsubfe %0,%3,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(ah)), "r" ((UDItype)(bh)), \ - "r" ((UDItype)(al)), "*rI" (-((UDItype)(bl))) \ - __CLOBBER_CC); \ - } else { \ - if (__builtin_constant_p (ah) && (ah) == 0) \ - __asm__ ("subf%I3c %1,%4,%3\n\tsubfze %0,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(bh)), \ - "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \ - __CLOBBER_CC); \ - else if (__builtin_constant_p (ah) && (ah) == ~(UDItype) 0) \ - __asm__ ("subf%I3c %1,%4,%3\n\tsubfme %0,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(bh)), \ - "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \ - __CLOBBER_CC); \ - else if (__builtin_constant_p (bh) && (bh) == 0) \ - __asm__ ("subf%I3c %1,%4,%3\n\taddme %0,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(ah)), \ - "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \ - __CLOBBER_CC); \ - else if (__builtin_constant_p (bh) && (bh) == ~(UDItype) 0) \ - __asm__ ("subf%I3c %1,%4,%3\n\taddze %0,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(ah)), \ - "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \ - __CLOBBER_CC); \ - else \ - __asm__ ("subf%I4c %1,%5,%4\n\tsubfe %0,%3,%2" \ - : "=r" (sh), "=&r" (sl) \ - : "r" ((UDItype)(ah)), "r" ((UDItype)(bh)), \ - "rI" ((UDItype)(al)), "r" ((UDItype)(bl)) \ - __CLOBBER_CC); \ - } \ - } while (0) -#endif /* ! _LONG_LONG_LIMB */ -#define count_leading_zeros(count, x) \ - __asm__ ("cntlzd %0,%1" : "=r" (count) : "r" (x)) -#define COUNT_LEADING_ZEROS_0 64 -#if __GMP_GNUC_PREREQ (4,8) -#define umul_ppmm(w1, w0, u, v) \ - do { \ - typedef unsigned int __ll_UTItype __attribute__((mode(TI))); \ - __ll_UTItype __ll = (__ll_UTItype)(u) * (v); \ - w1 = __ll >> 64; \ - w0 = __ll; \ - } while (0) -#endif -#if !defined (umul_ppmm) -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - UDItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("mulhdu %0,%1,%2" : "=r" (ph) : "%r" (__m0), "r" (__m1)); \ - (pl) = __m0 * __m1; \ - } while (0) -#endif -#define smul_ppmm(ph, pl, m0, m1) \ - do { \ - DItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("mulhd %0,%1,%2" : "=r" (ph) : "%r" (__m0), "r" (__m1)); \ - (pl) = __m0 * __m1; \ - } while (0) -#endif /* 64-bit PowerPC. */ - -#if defined (__pyr__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("addw %5,%1\n\taddwc %3,%0" \ - : "=r" (sh), "=&r" (sl) \ - : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \ - "%1" ((USItype)(al)), "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subw %5,%1\n\tsubwb %3,%0" \ - : "=r" (sh), "=&r" (sl) \ - : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \ - "1" ((USItype)(al)), "g" ((USItype)(bl))) -/* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */ -#define umul_ppmm(w1, w0, u, v) \ - ({union {UDItype __ll; \ - struct {USItype __h, __l;} __i; \ - } __x; \ - __asm__ ("movw %1,%R0\n\tuemul %2,%0" \ - : "=&r" (__x.__ll) \ - : "g" ((USItype) (u)), "g" ((USItype)(v))); \ - (w1) = __x.__i.__h; (w0) = __x.__i.__l;}) -#endif /* __pyr__ */ - -#if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("a %1,%5\n\tae %0,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "0" ((USItype)(ah)), "r" ((USItype)(bh)), \ - "%1" ((USItype)(al)), "r" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("s %1,%5\n\tse %0,%3" \ - : "=r" (sh), "=&r" (sl) \ - : "0" ((USItype)(ah)), "r" ((USItype)(bh)), \ - "1" ((USItype)(al)), "r" ((USItype)(bl))) -#define smul_ppmm(ph, pl, m0, m1) \ - __asm__ ( \ - "s r2,r2\n" \ -" mts r10,%2\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" m r2,%3\n" \ -" cas %0,r2,r0\n" \ -" mfs r10,%1" \ - : "=r" (ph), "=r" (pl) \ - : "%r" ((USItype)(m0)), "r" ((USItype)(m1)) \ - : "r2") -#define count_leading_zeros(count, x) \ - do { \ - if ((x) >= 0x10000) \ - __asm__ ("clz %0,%1" \ - : "=r" (count) : "r" ((USItype)(x) >> 16)); \ - else \ - { \ - __asm__ ("clz %0,%1" \ - : "=r" (count) : "r" ((USItype)(x))); \ - (count) += 16; \ - } \ - } while (0) -#endif /* RT/ROMP */ - -#if defined (__riscv64) && W_TYPE_SIZE == 64 -#define umul_ppmm(ph, pl, u, v) \ - do { \ - UDItype __u = (u), __v = (v); \ - (pl) = __u * __v; \ - __asm__ ("mulhu\t%2, %1, %0" : "=r" (ph) : "%r" (__u), "r" (__v)); \ - } while (0) -#endif - -#if (defined (__SH2__) || defined (__SH3__) || defined (__SH4__)) && W_TYPE_SIZE == 32 -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("dmulu.l %2,%3\n\tsts macl,%1\n\tsts mach,%0" \ - : "=r" (w1), "=r" (w0) : "r" (u), "r" (v) : "macl", "mach") -#endif - -#if defined (__sparc__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("addcc %r4,%5,%1\n\taddx %r2,%3,%0" \ - : "=r" (sh), "=&r" (sl) \ - : "rJ" (ah), "rI" (bh),"%rJ" (al), "rI" (bl) \ - __CLOBBER_CC) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subcc %r4,%5,%1\n\tsubx %r2,%3,%0" \ - : "=r" (sh), "=&r" (sl) \ - : "rJ" (ah), "rI" (bh), "rJ" (al), "rI" (bl) \ - __CLOBBER_CC) -/* FIXME: When gcc -mcpu=v9 is used on solaris, gcc/config/sol2-sld-64.h - doesn't define anything to indicate that to us, it only sets __sparcv8. */ -#if defined (__sparc_v9__) || defined (__sparcv9) -/* Perhaps we should use floating-point operations here? */ -#if 0 -/* Triggers a bug making mpz/tests/t-gcd.c fail. - Perhaps we simply need explicitly zero-extend the inputs? */ -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("mulx %2,%3,%%g1; srl %%g1,0,%1; srlx %%g1,32,%0" : \ - "=r" (w1), "=r" (w0) : "r" (u), "r" (v) : "g1") -#else -/* Use v8 umul until above bug is fixed. */ -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("umul %2,%3,%1;rd %%y,%0" : "=r" (w1), "=r" (w0) : "r" (u), "r" (v)) -#endif -/* Use a plain v8 divide for v9. */ -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { \ - USItype __q; \ - __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \ - : "=r" (__q) : "r" (n1), "r" (n0), "r" (d)); \ - (r) = (n0) - __q * (d); \ - (q) = __q; \ - } while (0) -#else -#if defined (__sparc_v8__) /* gcc normal */ \ - || defined (__sparcv8) /* gcc solaris */ \ - || HAVE_HOST_CPU_supersparc -/* Don't match immediate range because, 1) it is not often useful, - 2) the 'I' flag thinks of the range as a 13 bit signed interval, - while we want to match a 13 bit interval, sign extended to 32 bits, - but INTERPRETED AS UNSIGNED. */ -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("umul %2,%3,%1;rd %%y,%0" : "=r" (w1), "=r" (w0) : "r" (u), "r" (v)) - -#if HAVE_HOST_CPU_supersparc -#else -/* Don't use this on SuperSPARC because its udiv only handles 53 bit - dividends and will trap to the kernel for the rest. */ -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { \ - USItype __q; \ - __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \ - : "=r" (__q) : "r" (n1), "r" (n0), "r" (d)); \ - (r) = (n0) - __q * (d); \ - (q) = __q; \ - } while (0) -#endif /* HAVE_HOST_CPU_supersparc */ - -#else /* ! __sparc_v8__ */ -#if defined (__sparclite__) -/* This has hardware multiply but not divide. It also has two additional - instructions scan (ffs from high bit) and divscc. */ -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("umul %2,%3,%1;rd %%y,%0" : "=r" (w1), "=r" (w0) : "r" (u), "r" (v)) -#define udiv_qrnnd(q, r, n1, n0, d) \ - __asm__ ("! Inlined udiv_qrnnd\n" \ -" wr %%g0,%2,%%y ! Not a delayed write for sparclite\n" \ -" tst %%g0\n" \ -" divscc %3,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%%g1\n" \ -" divscc %%g1,%4,%0\n" \ -" rd %%y,%1\n" \ -" bl,a 1f\n" \ -" add %1,%4,%1\n" \ -"1: ! End of inline udiv_qrnnd" \ - : "=r" (q), "=r" (r) : "r" (n1), "r" (n0), "rI" (d) \ - : "%g1" __AND_CLOBBER_CC) -#define count_leading_zeros(count, x) \ - __asm__ ("scan %1,1,%0" : "=r" (count) : "r" (x)) -/* Early sparclites return 63 for an argument of 0, but they warn that future - implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 - undefined. */ -#endif /* __sparclite__ */ -#endif /* __sparc_v8__ */ -#endif /* __sparc_v9__ */ -/* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */ -#ifndef umul_ppmm -#define umul_ppmm(w1, w0, u, v) \ - __asm__ ("! Inlined umul_ppmm\n" \ -" wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr\n" \ -" sra %3,31,%%g2 ! Don't move this insn\n" \ -" and %2,%%g2,%%g2 ! Don't move this insn\n" \ -" andcc %%g0,0,%%g1 ! Don't move this insn\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,%3,%%g1\n" \ -" mulscc %%g1,0,%%g1\n" \ -" add %%g1,%%g2,%0\n" \ -" rd %%y,%1" \ - : "=r" (w1), "=r" (w0) : "%rI" (u), "r" (v) \ - : "%g1", "%g2" __AND_CLOBBER_CC) -#endif -#ifndef udiv_qrnnd -#ifndef LONGLONG_STANDALONE -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { UWtype __r; \ - (q) = __MPN(udiv_qrnnd) (&__r, (n1), (n0), (d)); \ - (r) = __r; \ - } while (0) -extern UWtype __MPN(udiv_qrnnd) (UWtype *, UWtype, UWtype, UWtype); -#endif /* LONGLONG_STANDALONE */ -#endif /* udiv_qrnnd */ -#endif /* __sparc__ */ - -#if defined (__sparc__) && W_TYPE_SIZE == 64 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ( \ - "addcc %r4,%5,%1\n" \ - " addccc %r6,%7,%%g0\n" \ - " addc %r2,%3,%0" \ - : "=r" (sh), "=&r" (sl) \ - : "rJ" ((UDItype)(ah)), "rI" ((UDItype)(bh)), \ - "%rJ" ((UDItype)(al)), "rI" ((UDItype)(bl)), \ - "%rJ" ((UDItype)(al) >> 32), "rI" ((UDItype)(bl) >> 32) \ - __CLOBBER_CC) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ( \ - "subcc %r4,%5,%1\n" \ - " subccc %r6,%7,%%g0\n" \ - " subc %r2,%3,%0" \ - : "=r" (sh), "=&r" (sl) \ - : "rJ" ((UDItype)(ah)), "rI" ((UDItype)(bh)), \ - "rJ" ((UDItype)(al)), "rI" ((UDItype)(bl)), \ - "rJ" ((UDItype)(al) >> 32), "rI" ((UDItype)(bl) >> 32) \ - __CLOBBER_CC) -#if __VIS__ >= 0x300 -#undef add_ssaaaa -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ( \ - "addcc %r4, %5, %1\n" \ - " addxc %r2, %r3, %0" \ - : "=r" (sh), "=&r" (sl) \ - : "rJ" ((UDItype)(ah)), "rJ" ((UDItype)(bh)), \ - "%rJ" ((UDItype)(al)), "rI" ((UDItype)(bl)) __CLOBBER_CC) -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - UDItype __m0 = (m0), __m1 = (m1); \ - (pl) = __m0 * __m1; \ - __asm__ ("umulxhi\t%2, %1, %0" \ - : "=r" (ph) \ - : "%r" (__m0), "r" (__m1)); \ - } while (0) -#define count_leading_zeros(count, x) \ - __asm__ ("lzd\t%1,%0" : "=r" (count) : "r" (x)) -/* Needed by count_leading_zeros_32 in sparc64.h. */ -#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB -#endif -#endif - -#if (defined (__vax) || defined (__vax__)) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("addl2 %5,%1\n\tadwc %3,%0" \ - : "=g" (sh), "=&g" (sl) \ - : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \ - "%1" ((USItype)(al)), "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("subl2 %5,%1\n\tsbwc %3,%0" \ - : "=g" (sh), "=&g" (sl) \ - : "0" ((USItype)(ah)), "g" ((USItype)(bh)), \ - "1" ((USItype)(al)), "g" ((USItype)(bl))) -#define smul_ppmm(xh, xl, m0, m1) \ - do { \ - union {UDItype __ll; \ - struct {USItype __l, __h;} __i; \ - } __x; \ - USItype __m0 = (m0), __m1 = (m1); \ - __asm__ ("emul %1,%2,$0,%0" \ - : "=g" (__x.__ll) : "g" (__m0), "g" (__m1)); \ - (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ - } while (0) -#define sdiv_qrnnd(q, r, n1, n0, d) \ - do { \ - union {DItype __ll; \ - struct {SItype __l, __h;} __i; \ - } __x; \ - __x.__i.__h = n1; __x.__i.__l = n0; \ - __asm__ ("ediv %3,%2,%0,%1" \ - : "=g" (q), "=g" (r) : "g" (__x.__ll), "g" (d)); \ - } while (0) -#if 0 -/* FIXME: This instruction appears to be unimplemented on some systems (vax - 8800 maybe). */ -#define count_trailing_zeros(count,x) \ - do { \ - __asm__ ("ffs 0, 31, %1, %0" \ - : "=g" (count) \ - : "g" ((USItype) (x))); \ - } while (0) -#endif -#endif /* vax */ - -#if defined (__z8000__) && W_TYPE_SIZE == 16 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ - : "=r" (sh), "=&r" (sl) \ - : "0" ((unsigned int)(ah)), "r" ((unsigned int)(bh)), \ - "%1" ((unsigned int)(al)), "rQR" ((unsigned int)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ - : "=r" (sh), "=&r" (sl) \ - : "0" ((unsigned int)(ah)), "r" ((unsigned int)(bh)), \ - "1" ((unsigned int)(al)), "rQR" ((unsigned int)(bl))) -#define umul_ppmm(xh, xl, m0, m1) \ - do { \ - union {long int __ll; \ - struct {unsigned int __h, __l;} __i; \ - } __x; \ - unsigned int __m0 = (m0), __m1 = (m1); \ - __asm__ ("mult %S0,%H3" \ - : "=r" (__x.__i.__h), "=r" (__x.__i.__l) \ - : "%1" (m0), "rQR" (m1)); \ - (xh) = __x.__i.__h; (xl) = __x.__i.__l; \ - (xh) += ((((signed int) __m0 >> 15) & __m1) \ - + (((signed int) __m1 >> 15) & __m0)); \ - } while (0) -#endif /* __z8000__ */ - -#endif /* __GNUC__ */ - -#endif /* NO_ASM */ - - -/* FIXME: "sidi" here is highly doubtful, should sometimes be "diti". */ -#if !defined (umul_ppmm) && defined (__umulsidi3) -#define umul_ppmm(ph, pl, m0, m1) \ - do { \ - UDWtype __ll = __umulsidi3 (m0, m1); \ - ph = (UWtype) (__ll >> W_TYPE_SIZE); \ - pl = (UWtype) __ll; \ - } while (0) -#endif - -#if !defined (__umulsidi3) -#define __umulsidi3(u, v) \ - ({UWtype __hi, __lo; \ - umul_ppmm (__hi, __lo, u, v); \ - ((UDWtype) __hi << W_TYPE_SIZE) | __lo; }) -#endif - - -#if defined (__cplusplus) -#define __longlong_h_C "C" -#else -#define __longlong_h_C -#endif - -/* Use mpn_umul_ppmm or mpn_udiv_qrnnd functions, if they exist. The "_r" - forms have "reversed" arguments, meaning the pointer is last, which - sometimes allows better parameter passing, in particular on 64-bit - hppa. */ - -#define mpn_umul_ppmm __MPN(umul_ppmm) -extern __longlong_h_C UWtype mpn_umul_ppmm (UWtype *, UWtype, UWtype); - -#if ! defined (umul_ppmm) && HAVE_NATIVE_mpn_umul_ppmm \ - && ! defined (LONGLONG_STANDALONE) -#define umul_ppmm(wh, wl, u, v) \ - do { \ - UWtype __umul_ppmm__p0; \ - (wh) = mpn_umul_ppmm (&__umul_ppmm__p0, (UWtype) (u), (UWtype) (v));\ - (wl) = __umul_ppmm__p0; \ - } while (0) -#endif - -#define mpn_umul_ppmm_r __MPN(umul_ppmm_r) -extern __longlong_h_C UWtype mpn_umul_ppmm_r (UWtype, UWtype, UWtype *); - -#if ! defined (umul_ppmm) && HAVE_NATIVE_mpn_umul_ppmm_r \ - && ! defined (LONGLONG_STANDALONE) -#define umul_ppmm(wh, wl, u, v) \ - do { \ - UWtype __umul_p0; \ - (wh) = mpn_umul_ppmm_r ((UWtype) (u), (UWtype) (v), &__umul_p0); \ - (wl) = __umul_p0; \ - } while (0) -#endif - -#define mpn_udiv_qrnnd __MPN(udiv_qrnnd) -extern __longlong_h_C UWtype mpn_udiv_qrnnd (UWtype *, UWtype, UWtype, UWtype); - -#if ! defined (udiv_qrnnd) && HAVE_NATIVE_mpn_udiv_qrnnd \ - && ! defined (LONGLONG_STANDALONE) -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { \ - UWtype __udiv_qrnnd_r; \ - (q) = mpn_udiv_qrnnd (&__udiv_qrnnd_r, \ - (UWtype) (n1), (UWtype) (n0), (UWtype) d); \ - (r) = __udiv_qrnnd_r; \ - } while (0) -#endif - -#define mpn_udiv_qrnnd_r __MPN(udiv_qrnnd_r) -extern __longlong_h_C UWtype mpn_udiv_qrnnd_r (UWtype, UWtype, UWtype, UWtype *); - -#if ! defined (udiv_qrnnd) && HAVE_NATIVE_mpn_udiv_qrnnd_r \ - && ! defined (LONGLONG_STANDALONE) -#define udiv_qrnnd(q, r, n1, n0, d) \ - do { \ - UWtype __udiv_qrnnd_r; \ - (q) = mpn_udiv_qrnnd_r ((UWtype) (n1), (UWtype) (n0), (UWtype) d, \ - &__udiv_qrnnd_r); \ - (r) = __udiv_qrnnd_r; \ - } while (0) -#endif - - -/* If this machine has no inline assembler, use C macros. */ - -#if !defined (add_ssaaaa) -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ - do { \ - UWtype __x; \ - UWtype __al = (al); \ - UWtype __bl = (bl); \ - __x = __al + __bl; \ - (sh) = (ah) + (bh) + (__x < __al); \ - (sl) = __x; \ - } while (0) -#endif - -#if !defined (sub_ddmmss) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ - do { \ - UWtype __x; \ - UWtype __al = (al); \ - UWtype __bl = (bl); \ - __x = __al - __bl; \ - (sh) = (ah) - (bh) - (__al < __bl); \ - (sl) = __x; \ - } while (0) -#endif - -/* If we lack umul_ppmm but have smul_ppmm, define umul_ppmm in terms of - smul_ppmm. */ -#if !defined (umul_ppmm) && defined (smul_ppmm) -#define umul_ppmm(w1, w0, u, v) \ - do { \ - UWtype __w1; \ - UWtype __xm0 = (u), __xm1 = (v); \ - smul_ppmm (__w1, w0, __xm0, __xm1); \ - (w1) = __w1 + (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \ - + (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \ - } while (0) -#endif - -/* If we still don't have umul_ppmm, define it using plain C. - - For reference, when this code is used for squaring (ie. u and v identical - expressions), gcc recognises __x1 and __x2 are the same and generates 3 - multiplies, not 4. The subsequent additions could be optimized a bit, - but the only place GMP currently uses such a square is mpn_sqr_basecase, - and chips obliged to use this generic C umul will have plenty of worse - performance problems than a couple of extra instructions on the diagonal - of sqr_basecase. */ - -#if !defined (umul_ppmm) -#define umul_ppmm(w1, w0, u, v) \ - do { \ - UWtype __x0, __x1, __x2, __x3; \ - UHWtype __ul, __vl, __uh, __vh; \ - UWtype __u = (u), __v = (v); \ - \ - __ul = __ll_lowpart (__u); \ - __uh = __ll_highpart (__u); \ - __vl = __ll_lowpart (__v); \ - __vh = __ll_highpart (__v); \ - \ - __x0 = (UWtype) __ul * __vl; \ - __x1 = (UWtype) __ul * __vh; \ - __x2 = (UWtype) __uh * __vl; \ - __x3 = (UWtype) __uh * __vh; \ - \ - __x1 += __ll_highpart (__x0);/* this can't give carry */ \ - __x1 += __x2; /* but this indeed can */ \ - if (__x1 < __x2) /* did we get it? */ \ - __x3 += __ll_B; /* yes, add it in the proper pos. */ \ - \ - (w1) = __x3 + __ll_highpart (__x1); \ - (w0) = (__x1 << W_TYPE_SIZE/2) + __ll_lowpart (__x0); \ - } while (0) -#endif - -/* If we don't have smul_ppmm, define it using umul_ppmm (which surely will - exist in one form or another. */ -#if !defined (smul_ppmm) -#define smul_ppmm(w1, w0, u, v) \ - do { \ - UWtype __w1; \ - UWtype __xm0 = (u), __xm1 = (v); \ - umul_ppmm (__w1, w0, __xm0, __xm1); \ - (w1) = __w1 - (-(__xm0 >> (W_TYPE_SIZE - 1)) & __xm1) \ - - (-(__xm1 >> (W_TYPE_SIZE - 1)) & __xm0); \ - } while (0) -#endif - -/* Define this unconditionally, so it can be used for debugging. */ -#define __udiv_qrnnd_c(q, r, n1, n0, d) \ - do { \ - UWtype __d1, __d0, __q1, __q0, __r1, __r0, __m; \ - \ - ASSERT ((d) != 0); \ - ASSERT ((n1) < (d)); \ - \ - __d1 = __ll_highpart (d); \ - __d0 = __ll_lowpart (d); \ - \ - __q1 = (n1) / __d1; \ - __r1 = (n1) - __q1 * __d1; \ - __m = __q1 * __d0; \ - __r1 = __r1 * __ll_B | __ll_highpart (n0); \ - if (__r1 < __m) \ - { \ - __q1--, __r1 += (d); \ - if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ - if (__r1 < __m) \ - __q1--, __r1 += (d); \ - } \ - __r1 -= __m; \ - \ - __q0 = __r1 / __d1; \ - __r0 = __r1 - __q0 * __d1; \ - __m = __q0 * __d0; \ - __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ - if (__r0 < __m) \ - { \ - __q0--, __r0 += (d); \ - if (__r0 >= (d)) \ - if (__r0 < __m) \ - __q0--, __r0 += (d); \ - } \ - __r0 -= __m; \ - \ - (q) = __q1 * __ll_B | __q0; \ - (r) = __r0; \ - } while (0) - -/* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through - __udiv_w_sdiv (defined in libgcc or elsewhere). */ -#if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) \ - && ! defined (LONGLONG_STANDALONE) -#define udiv_qrnnd(q, r, nh, nl, d) \ - do { \ - UWtype __r; \ - (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \ - (r) = __r; \ - } while (0) -__GMP_DECLSPEC UWtype __MPN(udiv_w_sdiv) (UWtype *, UWtype, UWtype, UWtype); -#endif - -/* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ -#if !defined (udiv_qrnnd) -#define UDIV_NEEDS_NORMALIZATION 1 -#define udiv_qrnnd __udiv_qrnnd_c -#endif - -#if !defined (count_leading_zeros) -#define count_leading_zeros(count, x) \ - do { \ - UWtype __xr = (x); \ - UWtype __a; \ - \ - if (W_TYPE_SIZE == 32) \ - { \ - __a = __xr < ((UWtype) 1 << 2*__BITS4) \ - ? (__xr < ((UWtype) 1 << __BITS4) ? 1 : __BITS4 + 1) \ - : (__xr < ((UWtype) 1 << 3*__BITS4) ? 2*__BITS4 + 1 \ - : 3*__BITS4 + 1); \ - } \ - else \ - { \ - for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ - if (((__xr >> __a) & 0xff) != 0) \ - break; \ - ++__a; \ - } \ - \ - (count) = W_TYPE_SIZE + 1 - __a - __clz_tab[__xr >> __a]; \ - } while (0) -/* This version gives a well-defined value for zero. */ -#define COUNT_LEADING_ZEROS_0 (W_TYPE_SIZE - 1) -#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB -#define COUNT_LEADING_ZEROS_SLOW -#endif - -/* clz_tab needed by mpn/x86/pentium/mod_1.asm in a fat binary */ -#if HAVE_HOST_CPU_FAMILY_x86 && WANT_FAT_BINARY -#define COUNT_LEADING_ZEROS_NEED_CLZ_TAB -#endif - -#ifdef COUNT_LEADING_ZEROS_NEED_CLZ_TAB -extern const unsigned char __GMP_DECLSPEC __clz_tab[129]; -#endif - -#if !defined (count_trailing_zeros) -#if !defined (COUNT_LEADING_ZEROS_SLOW) -/* Define count_trailing_zeros using an asm count_leading_zeros. */ -#define count_trailing_zeros(count, x) \ - do { \ - UWtype __ctz_x = (x); \ - UWtype __ctz_c; \ - ASSERT (__ctz_x != 0); \ - count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ - (count) = W_TYPE_SIZE - 1 - __ctz_c; \ - } while (0) -#else -/* Define count_trailing_zeros in plain C, assuming small counts are common. - We use clz_tab without ado, since the C count_leading_zeros above will have - pulled it in. */ -#define count_trailing_zeros(count, x) \ - do { \ - UWtype __ctz_x = (x); \ - int __ctz_c; \ - \ - if (LIKELY ((__ctz_x & 0xff) != 0)) \ - (count) = __clz_tab[__ctz_x & -__ctz_x] - 2; \ - else \ - { \ - for (__ctz_c = 8 - 2; __ctz_c < W_TYPE_SIZE - 2; __ctz_c += 8) \ - { \ - __ctz_x >>= 8; \ - if (LIKELY ((__ctz_x & 0xff) != 0)) \ - break; \ - } \ - \ - (count) = __ctz_c + __clz_tab[__ctz_x & -__ctz_x]; \ - } \ - } while (0) -#endif -#endif - -#ifndef UDIV_NEEDS_NORMALIZATION -#define UDIV_NEEDS_NORMALIZATION 0 -#endif - -/* Whether udiv_qrnnd is actually implemented with udiv_qrnnd_preinv, and - that hence the latter should always be used. */ -#ifndef UDIV_PREINV_ALWAYS -#define UDIV_PREINV_ALWAYS 0 -#endif diff --git a/python-bindings/CMakeLists.txt b/python-bindings/CMakeLists.txt index 4e0db652b7..2726399ed8 100644 --- a/python-bindings/CMakeLists.txt +++ b/python-bindings/CMakeLists.txt @@ -3,7 +3,7 @@ include(FetchContent) FetchContent_Declare( pybind11 GIT_REPOSITORY https://github.com/pybind/pybind11.git - GIT_TAG v2.10.0 + GIT_TAG v2.13.6 ) FetchContent_MakeAvailable(pybind11) diff --git a/rust-bindings/bls-dash-sys/build.rs b/rust-bindings/bls-dash-sys/build.rs index cc7cdd2d44..c5245e6c25 100644 --- a/rust-bindings/bls-dash-sys/build.rs +++ b/rust-bindings/bls-dash-sys/build.rs @@ -32,6 +32,7 @@ fn handle_command_output(output: Output) { #[cfg(not(feature = "apple"))] fn main() { let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); + let target_os = env::var("CARGO_CFG_TARGET_OS").unwrap(); // TODO: fix build for wasm32 on MacOS // errors with `error: linking with `rust-lld` failed: exit status: 1` @@ -39,6 +40,7 @@ fn main() { println!("Build for wasm32 is not fully supported"); return; } + println!("cargo:warning=Building bls-signatures for non-Apple target: {}", target_arch); let root_path = Path::new("../..") .canonicalize() @@ -63,12 +65,48 @@ fn main() { fs::create_dir_all(&bls_dash_build_path).expect("can't create build directory"); - let cmake_output = create_cross_cmake_command() + + let cmake_command_binding = create_cross_cmake_command(); + let mut cmake_command = cmake_command_binding; + + cmake_command .current_dir(&bls_dash_build_path) .arg("-DBUILD_BLS_PYTHON_BINDINGS=0") .arg("-DBUILD_BLS_TESTS=0") .arg("-DBUILD_BLS_BENCHMARKS=0") - .arg("-DBUILD_BLS_JS_BINDINGS=0") + .arg("-DBUILD_BLS_JS_BINDINGS=0"); + + // configure CMake for Android + if target_os.eq("android") { + let cmake_toolchain_path = env::var("CMAKE_TOOLCHAIN_FILE") + .or_else(|_| env::var("CARGO_NDK_CMAKE_TOOLCHAIN_PATH")) + .expect("Neither CMAKE_TOOLCHAIN_FILE nor CARGO_NDK_CMAKE_TOOLCHAIN_PATH environment variables are set"); + + let ndk_target = match env::var("CARGO_NDK_TARGET_ARCH") { + Ok(value) => value, // If set, use the value directly. + Err(_) => { + match target_arch.as_str() { + "aarch64" => "arm64-v8a".to_string(), + "arm" => "armeabi-v7a".to_string(), + "x86" => "x86".to_string(), + "x86_64" => "x86_64".to_string(), + _ => panic!("Unsupported target architecture for Android: {}", target_arch), + } + } + }; + + // Default to android-24 if ANDROID_PLATFORM is not specified + let android_abi = env::var("ANDROID_PLATFORM") + .or_else(|_| env::var("CARGO_NDK_ANDROID_PLATFORM")) + .unwrap_or_else(|_| "android-24".to_string()); + + cmake_command + .arg(format!("-DANDROID_PLATFORM={}", android_abi)) + .arg(format!("-DANDROID_ABI={}", ndk_target)) + .arg(format!("-DCMAKE_TOOLCHAIN_FILE={}", cmake_toolchain_path)); + } + + let cmake_output = cmake_command .arg("..") .output() .expect("can't run cmake"); @@ -100,8 +138,8 @@ fn main() { .collect(); include_paths.extend([ - bls_dash_build_path.join("_deps/relic-src/include"), - bls_dash_build_path.join("_deps/relic-build/include"), + bls_dash_build_path.join("depends/relic-src/include"), + bls_dash_build_path.join("depends/relic/include"), bls_dash_build_path.join("src"), root_path.join("include/dashbls"), bls_dash_build_path.join("depends/relic/include"), @@ -127,7 +165,8 @@ fn main() { cc.files(cpp_files) .includes(&include_paths) .cpp(true) - .flag_if_supported("-std=c++14"); + .flag_if_supported("-std=c++14") + .target(&env::var("TARGET").unwrap()); let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap(); @@ -196,6 +235,7 @@ fn main() { println!("cargo:rustc-link-lib=static=gmp"); } + println!("cargo:warning=########## bls_dash_build_path:{}", bls_dash_build_path.display()); // Generate rust code for c binding to src/lib.rs // println!("Generate C binding for rust:"); @@ -290,7 +330,7 @@ fn main() { let target = env::var("TARGET").unwrap(); - println!("Building bls-signatures for apple target: {}", target); + println!("cargo:warning=Building bls-signatures for Apple target: {}", target); let root_path = Path::new("../..") .canonicalize() .expect("can't get abs path"); @@ -305,6 +345,32 @@ fn main() { fs::remove_dir_all(&bls_dash_build_path).expect("can't clean build directory"); } fs::create_dir_all(&bls_dash_build_path).expect("can't create build directory"); + + let cc_path_output = Command::new("xcrun") + .arg("--sdk") + .arg("iphoneos") + .arg("--find") + .arg("clang") + .output() + .expect("Failed to find clang"); + let cc_path = String::from_utf8_lossy(&cc_path_output.stdout).trim().to_string(); + + let cxx_path_output = Command::new("xcrun") + .arg("--sdk") + .arg("iphoneos") + .arg("--find") + .arg("clang++") + .output() + .expect("Failed to find clang++"); + let cxx_path = String::from_utf8_lossy(&cxx_path_output.stdout).trim().to_string(); + + // Print the paths for clang and clang++ + println!("cargo:warning=CC path: {}", cc_path); + println!("cargo:warning=CXX path: {}", cxx_path); + + std::env::set_var("CC", cc_path); + std::env::set_var("CXX", cxx_path); + let output = Command::new("sh") .current_dir(&root_path) .arg(script) @@ -312,6 +378,7 @@ fn main() { .output() .expect("Failed to execute the shell script"); handle_command_output(output); + let (arch, platform) = match target.as_str() { "x86_64-apple-ios" => ("x86_64", "iphonesimulator"), "aarch64-apple-ios" => ("arm64", "iphoneos"), @@ -335,8 +402,8 @@ fn main() { .collect(); include_paths.extend([ - bls_dash_build_path.join(format!("relic-{}-{}/_deps/relic-src/include", platform, arch)), - bls_dash_build_path.join(format!("relic-{}-{}/_deps/relic-build/include", platform, arch)), + bls_dash_build_path.join(format!("relic-{}-{}/depends/relic-src/include", platform, arch)), + bls_dash_build_path.join(format!("relic-{}-{}/depends/relic/include", platform, arch)), bls_dash_build_path.join("contrib/relic/src"), root_path.join("src"), root_path.join("include/dashbls"), @@ -365,8 +432,10 @@ fn main() { println!("cargo:rustc-link-search={}", target_path.display()); println!("cargo:rustc-link-lib=static=gmp"); - // println!("cargo:rustc-link-lib=static=sodium"); - // println!("cargo:rustc-link-lib=static=relic_s"); + //println!("cargo:rustc-link-lib=c++"); + //println!("cargo:rustc-link-lib=c"); + //println!("cargo:rustc-link-lib=static=sodium"); + println!("cargo:rustc-link-lib=static=relic_s"); println!("cargo:rustc-link-lib=static=bls"); println!("cargo:rustc-link-search={}", bls_dash_src_path.display()); println!("cargo:rustc-link-lib=static=dashbls"); diff --git a/rust-bindings/bls-signatures/Cargo.toml b/rust-bindings/bls-signatures/Cargo.toml index 8c6f1e3c1d..5365ee4273 100644 --- a/rust-bindings/bls-signatures/Cargo.toml +++ b/rust-bindings/bls-signatures/Cargo.toml @@ -16,3 +16,4 @@ apple = ["bls-dash-sys/apple"] bls-dash-sys = { path = "../bls-dash-sys" } serde = { version= "1.0.160", features = ["derive"], optional = true} rand = { version= "0.8.5", optional = true} +hex = { version = "0.4.3"} diff --git a/rust-bindings/bls-signatures/src/elements.rs b/rust-bindings/bls-signatures/src/elements.rs index 3388ce022a..b671bdf6b5 100644 --- a/rust-bindings/bls-signatures/src/elements.rs +++ b/rust-bindings/bls-signatures/src/elements.rs @@ -1,4 +1,6 @@ use std::ffi::c_void; +use std::fmt::Debug; +use std::fmt::Formatter; use bls_dash_sys::{CoreMPLDeriveChildPkUnhardened, G1ElementFree, G1ElementFromBytes, G1ElementGenerator, G1ElementGetFingerprint, G1ElementIsEqual, G1ElementSerialize, G1ElementCopy, G2ElementCopy, G2ElementFree, G2ElementFromBytes, G2ElementIsEqual, G2ElementSerialize, ThresholdPublicKeyRecover, ThresholdSignatureRecover}; #[cfg(feature = "use_serde")] @@ -17,17 +19,28 @@ pub type PublicKey = G1Element; #[cfg(feature = "dash_helpers")] pub type Signature = G2Element; -#[derive(Debug)] pub struct G1Element { pub(crate) c_element: *mut c_void, } +// G1Element is immutable and thread safe +unsafe impl Send for G1Element {} +unsafe impl Sync for G1Element {} + impl PartialEq for G1Element { fn eq(&self, other: &Self) -> bool { unsafe { G1ElementIsEqual(self.c_element, other.c_element) } } } +impl Debug for G1Element { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let g1_hex = hex::encode(self.to_bytes().as_slice()); + + write!(f, "G1Element({:?})", g1_hex) + } +} + impl Eq for G1Element {} impl G1Element { @@ -181,17 +194,28 @@ impl Drop for G1Element { } } -#[derive(Debug)] pub struct G2Element { pub(crate) c_element: *mut c_void, } +// G2Element is immutable and thread safe +unsafe impl Send for G2Element {} +unsafe impl Sync for G2Element {} + impl PartialEq for G2Element { fn eq(&self, other: &Self) -> bool { unsafe { G2ElementIsEqual(self.c_element, other.c_element) } } } +impl Debug for G2Element { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let g2_hex = hex::encode(self.to_bytes().as_slice()); + + write!(f, "G2Element({:?})", g2_hex) + } +} + impl Eq for G2Element {} impl G2Element { @@ -311,6 +335,7 @@ impl Drop for G2Element { #[cfg(test)] mod tests { + use std::thread; use super::*; use crate::{ schemes::{AugSchemeMPL, Scheme}, @@ -365,4 +390,22 @@ mod tests { assert_eq!(g1_element.fingerprint(), 2093959050); } + + #[test] + fn should_be_thread_safe() { + let bytes = [ + 151, 241, 211, 167, 49, 151, 215, 148, 38, 149, 99, 140, 79, 169, 172, 15, 195, 104, + 140, 79, 151, 116, 185, 5, 161, 78, 58, 63, 23, 27, 172, 88, 108, 85, 232, 63, 249, + 122, 26, 239, 251, 58, 240, 10, 219, 34, 198, 187, + ]; + + let g1_element = + G1Element::from_bytes(&bytes).expect("should create g1 element from bytes"); + + let test_thread = thread::spawn(move|| { + assert_eq!(g1_element.fingerprint(), 2093959050); + }); + + test_thread.join().unwrap(); + } } diff --git a/rust-bindings/bls-signatures/src/legacy/elements.rs b/rust-bindings/bls-signatures/src/legacy/elements.rs index ca205a8073..eae5bc4eda 100644 --- a/rust-bindings/bls-signatures/src/legacy/elements.rs +++ b/rust-bindings/bls-signatures/src/legacy/elements.rs @@ -5,6 +5,10 @@ impl G1Element { self.to_bytes_with_legacy_flag(true) } + pub fn serialize(&self) -> Box<[u8; G1_ELEMENT_SIZE]> { + self.to_bytes_with_legacy_flag(false) + } + pub fn from_bytes_legacy(bytes: &[u8]) -> Result { Self::from_bytes_with_legacy_flag(bytes, true) } @@ -22,4 +26,8 @@ impl G2Element { pub fn serialize_legacy(&self) -> Box<[u8; G2_ELEMENT_SIZE]> { self.to_bytes_with_legacy_flag(true) } + + pub fn serialize(&self) -> Box<[u8; G2_ELEMENT_SIZE]> { + self.to_bytes_with_legacy_flag(false) + } } diff --git a/rust-bindings/bls-signatures/src/lib.rs b/rust-bindings/bls-signatures/src/lib.rs index e6d76b8149..fdfc6ddef3 100644 --- a/rust-bindings/bls-signatures/src/lib.rs +++ b/rust-bindings/bls-signatures/src/lib.rs @@ -101,4 +101,26 @@ mod tests { grandchild_sk_u.g1_element().expect("cannot get public key") ); } + + #[test] + fn test_bls_public_key() { + let seed = b"seedweedseedweedseedweedseedweed"; + let scheme = LegacySchemeMPL::new(); + + let private_key = PrivateKey::key_gen(&scheme, seed).expect("unable to generate private key"); + let public_key = private_key.g1_element().expect("unable to get public key"); + + let expected_priv_key = vec![92, 116, 13, 32, 66, 150, 74, 240, 121, 255, 94, 222, 127, 180, 19, 10, 244, 212, 173, 51, 91, 198, 162, 132, 230, 105, 134, 255, 125, 191, 198, 223]; + let expected_pub_key = vec![129, 171, 183, 152, 50, 52, 28, 18, 241, 75, 118, 255, 58, 136, 184, 52, 247, 229, 14, 221, 40, 117, 194, 142, 2, 208, 193, 215, 131, 17, 234, 195, 229, 23, 249, 239, 139, 176, 18, 187, 102, 55, 162, 76, 48, 88, 228, 150]; + + assert_eq!( + private_key.to_bytes().as_slice(), + expected_priv_key + ); + + assert_eq!( + public_key.to_bytes().as_slice(), + expected_pub_key + ); + } } diff --git a/rust-bindings/bls-signatures/src/private_key.rs b/rust-bindings/bls-signatures/src/private_key.rs index bc74d710f3..ab129856cd 100755 --- a/rust-bindings/bls-signatures/src/private_key.rs +++ b/rust-bindings/bls-signatures/src/private_key.rs @@ -1,4 +1,5 @@ use std::{ffi::c_void, ops::Mul}; +use std::fmt::{Debug, Formatter}; use bls_dash_sys::{ CoreMPLDeriveChildSk, CoreMPLDeriveChildSkUnhardened, CoreMPLKeyGen, G1ElementMul, @@ -13,7 +14,6 @@ use crate::{schemes::Scheme, utils::{c_err_to_result, SecureBox}, BasicSchemeMPL pub const PRIVATE_KEY_SIZE: usize = 32; // TODO somehow extract it from bls library -#[derive(Debug)] pub struct PrivateKey { pub(crate) c_private_key: *mut c_void, } @@ -26,6 +26,13 @@ impl PartialEq for PrivateKey { impl Eq for PrivateKey {} +impl Debug for PrivateKey { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + let private_key_hex = hex::encode(self.to_bytes().as_slice()); + + write!(f, "PrivateKey({:?})", private_key_hex) + } +} impl Mul for PrivateKey { type Output = Result;