diff --git a/.cirrus.yml b/.cirrus.yml index 1bbdbdff..9ee488a8 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -17,4 +17,4 @@ freebsd_task: - opam install -t ocaml-solo5 --deps-only build_script: opam reinstall -t ocaml-solo5 test_script: - - MODE=hvt opam exec -- dune build --root example + - MODE=hvt opam exec -- dune build --root example --display short diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4d340bec..40c2dccf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,14 +1,25 @@ name: Test -on: [push, pull_request] +on: + push: + branches: + - main + pull_request: jobs: test: strategy: matrix: + runner: + - ubuntu-latest + - ubuntu-24.04-arm ocaml-compiler: - - 5.4.1 - 5.5.0 - name: OCaml ${{ matrix.ocaml-compiler }} - runs-on: ubuntu-latest + include: + - runner: ubuntu-latest + ocaml-compiler: 5.4.1 + name: >- + OCaml ${{ matrix.ocaml-compiler }} + ${{ case(matrix.runner=='ubuntu-latest', 'x86_64', 'arm64') }} + runs-on: ${{ matrix.runner }} steps: - uses: actions/checkout@v7 - uses: ocaml/setup-ocaml@v3 @@ -18,7 +29,9 @@ jobs: *.opam !ocaml-solo5-cross-aarch64.opam - name: Install ocaml-solo5 and dune - run: opam install ocaml-solo5 conf-libseccomp dune fmt + run: | + opam install conf-libseccomp dune fmt \ + ocaml-solo5 --verbose-on=ocaml-solo5 - name: Show the toolchain configuration run: | set -x @@ -26,7 +39,7 @@ jobs: opam exec -- ocamlfind -toolchain solo5 printconf opam exec -- ocamlfind -toolchain solo5 list - name: Compile examples with hvt - run: MODE=hvt opam exec -- dune build --root example + run: MODE=hvt opam exec -- dune build --root example --display short - name: Run the hello example with hvt run: | set -x @@ -34,13 +47,17 @@ jobs: --context solo5 --no-print-directory ./hello.exe |& tee hello.path sudo setfacl -m u:${USER}:rw /dev/kvm opam exec -- solo5-hvt -- "example/$(cat hello.path)" + if: matrix.runner == 'ubuntu-latest' - name: Compile examples with spt - run: MODE=spt opam exec -- dune build --root example + run: MODE=spt opam exec -- dune build --root example --display short - name: Run examples with spt - run: MODE=spt opam exec -- dune runtest --root example + run: MODE=spt opam exec -- dune runtest --root example _build/solo5 - name: Compile examples with virtio - run: MODE=virtio opam exec -- dune build --root example + run: MODE=virtio opam exec -- dune build --root example --display short + if: matrix.runner == 'ubuntu-latest' - name: Compile examples with muen - run: MODE=muen opam exec -- dune build --root example + run: MODE=muen opam exec -- dune build --root example --display short + if: matrix.runner == 'ubuntu-latest' - name: Compile examples with xen - run: MODE=xen opam exec -- dune build --root example + run: MODE=xen opam exec -- dune build --root example --display short + if: matrix.runner == 'ubuntu-latest' diff --git a/openlibm/.github/dependabot.yml b/openlibm/.github/dependabot.yml new file mode 100644 index 00000000..d60f0707 --- /dev/null +++ b/openlibm/.github/dependabot.yml @@ -0,0 +1,7 @@ +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" # Location of package manifests + schedule: + interval: "monthly" diff --git a/openlibm/.github/workflows/ci.yml b/openlibm/.github/workflows/ci.yml new file mode 100644 index 00000000..cdb93582 --- /dev/null +++ b/openlibm/.github/workflows/ci.yml @@ -0,0 +1,93 @@ +name: CI +on: + pull_request: + branches: + - master + push: + branches: + - master + tags: '*' +jobs: + test-unix: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: + - ubuntu-latest + - macos-latest + steps: + - uses: actions/checkout@v4 + - run: make + - run: make test + windows: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + include: + - { sys: mingw64, env: x86_64 } + - { sys: mingw32, env: i686 } + - { sys: ucrt64, env: ucrt-x86_64 } # Experimental! + - { sys: clang64, env: clang-x86_64 } # Experimental! + defaults: + run: + shell: msys2 {0} + steps: + - uses: actions/checkout@v4 + - name: Set up the desired MSYS2 environment + uses: msys2/setup-msys2@v2 + with: + msystem: ${{matrix.sys}} + install: base-devel mingw-w64-${{matrix.env}}-toolchain + - run: make + - run: make test + code-coverage-old: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Setup LCOV + uses: hrishikesh-kadam/setup-lcov@v1 + - name: Build and Run tests + run: make coverage -j + # - name: Upload coverage to Codecov + # uses: codecov/codecov-action@v5 + # with: + # files: ./cov-html/libopenlibm.info + # token: ${{ secrets.CODECOV_TOKEN }} + - uses: actions/upload-artifact@v4 + with: + name: code-coverage-report-old + path: ./cov-html/ + code-coverage: + runs-on: ubuntu-latest + steps: + - name: Checkout Openlibm + uses: actions/checkout@v4 + - name: Checkout Openlibm-test + uses: actions/checkout@v4 + with: + repository: 'JuliaMath/openlibm-test' + path: 'openlibm-test' + - name: Setup LCOV + uses: hrishikesh-kadam/setup-lcov@v1 + - name: Build Openlibm + run: make -j`nproc` CODE_COVERAGE=1 + - name: Run Test + run: | + make -j`nproc` -C openlibm-test \ + USE_OPENLIBM=1 OPENLIBM_HOME="$(pwd)" \ + SKIP_FP_EXCEPT_TEST=1 \ + - name: Show Test Result + run: cat openlibm-test/src/REPORT + - name: Gen Coverage Report + run: make gen-cov-report + - name: Upload coverage to Codecov + uses: codecov/codecov-action@v5 + with: + files: ./cov-html/libopenlibm.info + token: ${{ secrets.CODECOV_TOKEN }} + - uses: actions/upload-artifact@v4 + with: + name: code-coverage-report + path: ./cov-html/ diff --git a/openlibm/.github/workflows/cross-loongarch64.yml b/openlibm/.github/workflows/cross-loongarch64.yml new file mode 100644 index 00000000..1c8e7691 --- /dev/null +++ b/openlibm/.github/workflows/cross-loongarch64.yml @@ -0,0 +1,54 @@ +# merge this file into cross.yml +# when we can `sudo apt install gcc-loongarch64-linux-gnu` on ubuntu +name: Cross + +on: + pull_request: + branches: + - master + push: + branches: + - master + tags: '*' + +jobs: + build-cross-qemu: + # TODO: We need Ubuntu 24.04 to use newer version of qemu, + # switch to ubuntu-latest when `ubuntu-latest >= 24.04` + runs-on: ubuntu-24.04 + name: build-cross-qemu-${{ matrix.config.arch }} + strategy: + fail-fast: false + matrix: + config: + - { arch: loongarch64, triple: loongarch64-linux-gnu } + env: + ARCH: ${{ matrix.config.arch }} + TRIPLE: ${{ matrix.config.triple }} + steps: + - uses: actions/checkout@v4 + - name: Install qemu + run: | + sudo apt update + sudo apt install -y qemu-user qemu-user-binfmt + - name: Install gcc-${{ matrix.config.triple }} + # package gcc-loongarch64-linux-gnu seems not exist + # https://packages.debian.org/sid/amd64/gcc-loongarch64-linux-gnu + run: sudo apt install -y gcc-14-loongarch64-linux-gnu + - name: Build with ${{ matrix.config.triple }}-gcc + run: | + make ARCH=$ARCH TOOLPREFIX=$TRIPLE- \ + CC='loongarch64-linux-gnu-gcc-14' \ + AR='loongarch64-linux-gnu-gcc-ar-14' \ + - name: Build tests + run: | + make -C test ARCH=$ARCH TOOLPREFIX=$TRIPLE- \ + CC='loongarch64-linux-gnu-gcc-14' \ + AR='loongarch64-linux-gnu-gcc-ar-14' \ + - name: Run Tests + env: + QEMU_EXEC: qemu-${{ matrix.config.arch }} + CROSS_LIB: /usr/${{ matrix.config.triple }} + run: | + $QEMU_EXEC -L . -L $CROSS_LIB/ test/test-float + $QEMU_EXEC -L . -L $CROSS_LIB/ test/test-double diff --git a/openlibm/.github/workflows/cross.yml b/openlibm/.github/workflows/cross.yml new file mode 100644 index 00000000..267341ad --- /dev/null +++ b/openlibm/.github/workflows/cross.yml @@ -0,0 +1,53 @@ +name: Cross + +on: + pull_request: + branches: + - master + push: + branches: + - master + tags: '*' + +jobs: + build-cross-qemu: + # TODO: We need Ubuntu 24.04 to use newer version of qemu, + # switch to ubuntu-latest when `ubuntu-latest >= 24.04` + runs-on: ubuntu-24.04 + name: build-cross-qemu-${{ matrix.config.arch }} + strategy: + fail-fast: false + matrix: + config: + - { arch: arm, triple: arm-linux-gnueabihf } + - { arch: aarch64, triple: aarch64-linux-gnu } + - { arch: ppc, triple: powerpc-linux-gnu } + - { arch: ppc64, triple: powerpc64-linux-gnu } + - { arch: ppc64le, triple: powerpc64le-linux-gnu } + - { arch: mips, triple: mips-linux-gnu } + - { arch: mipsel, triple: mipsel-linux-gnu } + # Builds successfully, but tests fail. + # - { arch: mips64, triple: mips64-linux-gnuabi64 } + # - { arch: mips64el, triple: mips64el-linux-gnuabi64 } + - { arch: riscv64, triple: riscv64-linux-gnu } + - { arch: s390x, triple: s390x-linux-gnu } + env: + ARCH: ${{ matrix.config.arch }} + TRIPLE: ${{ matrix.config.triple }} + steps: + - uses: actions/checkout@v4 + - name: Install qemu and toolchain gcc-${{ matrix.config.triple }} + run: | + sudo apt update + sudo apt install qemu-user qemu-user-binfmt gcc-$TRIPLE -y + - name: Build with ${{ matrix.config.triple }}-gcc + run: make ARCH=$ARCH TOOLPREFIX=$TRIPLE- + - name: Build tests + run: make -C test ARCH=$ARCH TOOLPREFIX=$TRIPLE- + - name: Run Tests + env: + QEMU_EXEC: qemu-${{ matrix.config.arch }} + CROSS_LIB: /usr/${{ matrix.config.triple }} + run: | + $QEMU_EXEC -L . -L $CROSS_LIB/ test/test-float + $QEMU_EXEC -L . -L $CROSS_LIB/ test/test-double diff --git a/openlibm/.gitignore b/openlibm/.gitignore index e7e0c44f..9f5c0be6 100644 --- a/openlibm/.gitignore +++ b/openlibm/.gitignore @@ -5,3 +5,9 @@ *.so* *.dylib* *.pc + +# code coverage +openlibm-test +cov-html/ +*.gcda +*.gcno diff --git a/openlibm/.travis.yml b/openlibm/.travis.yml deleted file mode 100644 index 19e6b11e..00000000 --- a/openlibm/.travis.yml +++ /dev/null @@ -1,73 +0,0 @@ -# We require a full (virtual) machine to load the kernel module for -# binfmt support, which is needed to test other architectures besides -# x86 using qemu user emulation. (This will not work in a container.) -sudo: required -dist: trusty -language: c - -script: - - make $FLAGS - - make check $FLAGS $TEST_FLAGS - - make clean && git status --ignored --porcelain && test -z "$(git status --ignored --porcelain)" - -matrix: - include: - - compiler: clang - os: linux - addons: - apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.7 - packages: - - clang-3.7 - env: FLAGS="CC=clang-3.7 CXX=clang++-3.7" - - - os: osx - env: FLAGS="CC=clang" - - - os: linux - env: FLAGS="CC=gcc" - - - os: linux - env: FLAGS="CC=gcc ARCH=i686" # implies -m32 -march=i686 - addons: - apt: - packages: - - gcc-multilib - - - os: linux - env: FLAGS="CC=aarch64-linux-gnu-gcc" TEST_FLAGS="LDFLAGS=-static" - addons: - apt: - packages: - - gcc-aarch64-linux-gnu - - libc6-dev-arm64-cross - - qemu-user-static - - binfmt-support - - - os: linux - env: FLAGS="CC=arm-linux-gnueabihf-gcc" TEST_FLAGS="LDFLAGS=-static" - addons: - apt: - packages: - - gcc-arm-linux-gnueabihf - - libc6-dev-armhf-cross - - qemu-user-static - - binfmt-support - - # This works, but only if qemu-user-static is >= v2.4. This is not the - # case on the default trusty images, so we add a PPA that has qemu 2.5 - - os: linux - env: FLAGS="CC=powerpc64le-linux-gnu-gcc" TEST_FLAGS="LDFLAGS=-static" - addons: - apt: - sources: - - sourceline: "ppa:gns3/qemu" - packages: - - gcc-powerpc64le-linux-gnu - - libc6-dev-ppc64el-cross - - qemu-user-static - - binfmt-support -notifications: - email: false diff --git a/openlibm/CMakeLists.txt b/openlibm/CMakeLists.txt new file mode 100755 index 00000000..81045e25 --- /dev/null +++ b/openlibm/CMakeLists.txt @@ -0,0 +1,576 @@ +cmake_minimum_required(VERSION 3.25) + +# Get version string from Make.inc +file(READ "${CMAKE_CURRENT_LIST_DIR}/Make.inc" MAKE_FILE) +string(REGEX MATCH "VERSION = ([0-9\.]+)" _ ${MAKE_FILE}) + +project(openlibm + VERSION ${CMAKE_MATCH_1} + LANGUAGES C ASM) + +option(BUILD_SHARED_LIBS "Build using shared libraries" ON) + +add_library("${PROJECT_NAME}") + +# Find the relevant folder depending on the architecture +set(OPENLIBM_ARCH_FOLDER ${CMAKE_SYSTEM_PROCESSOR}) +string(TOLOWER "${OPENLIBM_ARCH_FOLDER}" OPENLIBM_ARCH_FOLDER) + +if(${OPENLIBM_ARCH_FOLDER} STREQUAL "amd64" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "x86_64") + set(OPENLIBM_ARCH_FOLDER "amd64") +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "arm64" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "aarch64") + set(OPENLIBM_ARCH_FOLDER "aarch64") +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "armv7-a") + set(OPENLIBM_ARCH_FOLDER "arm") +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "x86" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "i686") + set(OPENLIBM_ARCH_FOLDER "i387") +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "powerpc") + set(OPENLIBM_ARCH_FOLDER "powerpc") +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "riscv64") + set(OPENLIBM_ARCH_FOLDER "riscv64") +else() + message(FATAL_ERROR "${PROJECT_NAME} not set up for detected architecture: ${OPENLIBM_ARCH_FOLDER}") +endif() + + +# Compile flags +list(APPEND C_ASM_COMPILE_FLAGS "-ffp-contract=off" "-fno-fast-math" "-fno-rounding-math" "-fno-math-errno") +list(APPEND C_ASM_COMPILE_FLAGS "-fPIC" "-std=c99" "-fno-builtin") +list(APPEND C_ASM_COMPILE_FLAGS "-Wall" "-Wno-implicit-function-declaration") +list(APPEND C_ASM_COMPILE_FLAGS "-DASSEMBLER" "-D__BSD_VISIBLE" "-O3") + +# Compiler-specific compile flags +if("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") + list(APPEND C_ASM_COMPILE_FLAGS "-fno-strict-aliasing" "-ffp-exception-behavior=strict") +elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + list(APPEND C_ASM_COMPILE_FLAGS "-fno-gnu89-inline") +else() + message(FATAL_ERROR "${PROJECT_NAME} not set up to be compiled with ${CMAKE_C_COMPILER_ID}") +endif() + +# Architecture-specific compile flags - take advantage of sse on x86 +if(${OPENLIBM_ARCH_FOLDER} STREQUAL "i387") + list(APPEND C_ASM_COMPILE_FLAGS "-march=i686" "-m32" "-msse2" "-mfpmath=sse") +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "amd64") + list(APPEND C_ASM_COMPILE_FLAGS "-m64" "-msse2" "-mfpmath=sse") +endif() + +# Suppress warnings if requested +if(OPENLIBM_SUPPRESS_WARNINGS) + list(APPEND C_ASM_COMPILE_FLAGS "-w") +endif() + +# Add compile flags +target_compile_options("${PROJECT_NAME}" PUBLIC ${C_ASM_COMPILE_FLAGS}) + +# Project Source +set(PROJECT_SRC "${CMAKE_CURRENT_SOURCE_DIR}") + +# Common +list(APPEND OPENLIBM_C_SOURCE + # src + "${PROJECT_SRC}/src/common.c" + "${PROJECT_SRC}/src/e_acos.c" + "${PROJECT_SRC}/src/e_acosf.c" + "${PROJECT_SRC}/src/e_acosh.c" + "${PROJECT_SRC}/src/e_acoshf.c" + "${PROJECT_SRC}/src/e_asin.c" + "${PROJECT_SRC}/src/e_asinf.c" + "${PROJECT_SRC}/src/e_atan2.c" + "${PROJECT_SRC}/src/e_atan2f.c" + "${PROJECT_SRC}/src/e_atanh.c" + "${PROJECT_SRC}/src/e_atanhf.c" + "${PROJECT_SRC}/src/e_cosh.c" + "${PROJECT_SRC}/src/e_coshf.c" + "${PROJECT_SRC}/src/e_exp.c" + "${PROJECT_SRC}/src/e_expf.c" + "${PROJECT_SRC}/src/e_fmod.c" + "${PROJECT_SRC}/src/e_fmodf.c" + "${PROJECT_SRC}/src/e_hypot.c" + "${PROJECT_SRC}/src/e_hypotf.c" + "${PROJECT_SRC}/src/e_j0.c" + "${PROJECT_SRC}/src/e_j0f.c" + "${PROJECT_SRC}/src/e_j1.c" + "${PROJECT_SRC}/src/e_j1f.c" + "${PROJECT_SRC}/src/e_jn.c" + "${PROJECT_SRC}/src/e_jnf.c" + "${PROJECT_SRC}/src/e_lgamma.c" + "${PROJECT_SRC}/src/e_lgamma_r.c" + "${PROJECT_SRC}/src/e_lgammaf.c" + "${PROJECT_SRC}/src/e_lgammaf_r.c" + "${PROJECT_SRC}/src/e_log.c" + "${PROJECT_SRC}/src/e_log10.c" + "${PROJECT_SRC}/src/e_log10f.c" + "${PROJECT_SRC}/src/e_log2.c" + "${PROJECT_SRC}/src/e_log2f.c" + "${PROJECT_SRC}/src/e_logf.c" + "${PROJECT_SRC}/src/e_pow.c" + "${PROJECT_SRC}/src/e_powf.c" + "${PROJECT_SRC}/src/e_remainder.c" + "${PROJECT_SRC}/src/e_remainderf.c" + "${PROJECT_SRC}/src/e_rem_pio2.c" + "${PROJECT_SRC}/src/e_rem_pio2f.c" + "${PROJECT_SRC}/src/e_sinh.c" + "${PROJECT_SRC}/src/e_sinhf.c" + "${PROJECT_SRC}/src/e_sqrt.c" + "${PROJECT_SRC}/src/e_sqrtf.c" + "${PROJECT_SRC}/src/k_cos.c" + "${PROJECT_SRC}/src/k_exp.c" + "${PROJECT_SRC}/src/k_expf.c" + "${PROJECT_SRC}/src/k_rem_pio2.c" + "${PROJECT_SRC}/src/k_sin.c" + "${PROJECT_SRC}/src/k_tan.c" + "${PROJECT_SRC}/src/k_cosf.c" + "${PROJECT_SRC}/src/k_sinf.c" + "${PROJECT_SRC}/src/k_tanf.c" + "${PROJECT_SRC}/src/s_asinh.c" + "${PROJECT_SRC}/src/s_asinhf.c" + "${PROJECT_SRC}/src/s_atan.c" + "${PROJECT_SRC}/src/s_atanf.c" + "${PROJECT_SRC}/src/s_carg.c" + "${PROJECT_SRC}/src/s_cargf.c" + "${PROJECT_SRC}/src/s_cbrt.c" + "${PROJECT_SRC}/src/s_cbrtf.c" + "${PROJECT_SRC}/src/s_ceil.c" + "${PROJECT_SRC}/src/s_ceilf.c" + "${PROJECT_SRC}/src/s_copysign.c" + "${PROJECT_SRC}/src/s_copysignf.c" + "${PROJECT_SRC}/src/s_cos.c" + "${PROJECT_SRC}/src/s_cosf.c" + "${PROJECT_SRC}/src/s_csqrt.c" + "${PROJECT_SRC}/src/s_csqrtf.c" + "${PROJECT_SRC}/src/s_erf.c" + "${PROJECT_SRC}/src/s_erff.c" + "${PROJECT_SRC}/src/s_exp2.c" + "${PROJECT_SRC}/src/s_exp2f.c" + "${PROJECT_SRC}/src/s_expm1.c" + "${PROJECT_SRC}/src/s_expm1f.c" + "${PROJECT_SRC}/src/s_fabs.c" + "${PROJECT_SRC}/src/s_fabsf.c" + "${PROJECT_SRC}/src/s_fdim.c" + "${PROJECT_SRC}/src/s_floor.c" + "${PROJECT_SRC}/src/s_floorf.c" + "${PROJECT_SRC}/src/s_fmax.c" + "${PROJECT_SRC}/src/s_fmaxf.c" + "${PROJECT_SRC}/src/s_fmin.c" + "${PROJECT_SRC}/src/s_fminf.c" + "${PROJECT_SRC}/src/s_fpclassify.c" + "${PROJECT_SRC}/src/s_frexp.c" + "${PROJECT_SRC}/src/s_frexpf.c" + "${PROJECT_SRC}/src/s_ilogb.c" + "${PROJECT_SRC}/src/s_ilogbf.c" + "${PROJECT_SRC}/src/s_isinf.c" + "${PROJECT_SRC}/src/s_isfinite.c" + "${PROJECT_SRC}/src/s_isnormal.c" + "${PROJECT_SRC}/src/s_isnan.c" + "${PROJECT_SRC}/src/s_log1p.c" + "${PROJECT_SRC}/src/s_log1pf.c" + "${PROJECT_SRC}/src/s_logb.c" + "${PROJECT_SRC}/src/s_logbf.c" + "${PROJECT_SRC}/src/s_modf.c" + "${PROJECT_SRC}/src/s_modff.c" + "${PROJECT_SRC}/src/s_nextafter.c" + "${PROJECT_SRC}/src/s_nextafterf.c" + "${PROJECT_SRC}/src/s_nexttowardf.c" + "${PROJECT_SRC}/src/s_remquo.c" + "${PROJECT_SRC}/src/s_remquof.c" + "${PROJECT_SRC}/src/s_rint.c" + "${PROJECT_SRC}/src/s_rintf.c" + "${PROJECT_SRC}/src/s_round.c" + "${PROJECT_SRC}/src/s_roundf.c" + "${PROJECT_SRC}/src/s_scalbln.c" + "${PROJECT_SRC}/src/s_scalbn.c" + "${PROJECT_SRC}/src/s_scalbnf.c" + "${PROJECT_SRC}/src/s_signbit.c" + "${PROJECT_SRC}/src/s_signgam.c" + "${PROJECT_SRC}/src/s_sin.c" + "${PROJECT_SRC}/src/s_sincos.c" + "${PROJECT_SRC}/src/s_sinf.c" + "${PROJECT_SRC}/src/s_sincosf.c" + "${PROJECT_SRC}/src/s_tan.c" + "${PROJECT_SRC}/src/s_tanf.c" + "${PROJECT_SRC}/src/s_tanh.c" + "${PROJECT_SRC}/src/s_tanhf.c" + "${PROJECT_SRC}/src/s_tgammaf.c" + "${PROJECT_SRC}/src/s_trunc.c" + "${PROJECT_SRC}/src/s_truncf.c" + "${PROJECT_SRC}/src/s_cpow.c" + "${PROJECT_SRC}/src/s_cpowf.c" + "${PROJECT_SRC}/src/w_cabs.c" + "${PROJECT_SRC}/src/w_cabsf.c" + + "${PROJECT_SRC}/src/s_fma.c" + "${PROJECT_SRC}/src/s_fmaf.c" + "${PROJECT_SRC}/src/s_lrint.c" + "${PROJECT_SRC}/src/s_lrintf.c" + "${PROJECT_SRC}/src/s_lround.c" + "${PROJECT_SRC}/src/s_lroundf.c" + "${PROJECT_SRC}/src/s_llrint.c" + "${PROJECT_SRC}/src/s_llrintf.c" + "${PROJECT_SRC}/src/s_llround.c" + "${PROJECT_SRC}/src/s_llroundf.c" + "${PROJECT_SRC}/src/s_nearbyint.c" + + # C99 complex functions + "${PROJECT_SRC}/src/s_ccosh.c" + "${PROJECT_SRC}/src/s_ccoshf.c" + "${PROJECT_SRC}/src/s_cexp.c" + "${PROJECT_SRC}/src/s_cexpf.c" + "${PROJECT_SRC}/src/s_cimag.c" + "${PROJECT_SRC}/src/s_cimagf.c" + "${PROJECT_SRC}/src/s_conj.c" + "${PROJECT_SRC}/src/s_conjf.c" + "${PROJECT_SRC}/src/s_cproj.c" + "${PROJECT_SRC}/src/s_cprojf.c" + "${PROJECT_SRC}/src/s_creal.c" + "${PROJECT_SRC}/src/s_crealf.c" + "${PROJECT_SRC}/src/s_csinh.c" + "${PROJECT_SRC}/src/s_csinhf.c" + "${PROJECT_SRC}/src/s_ctanh.c" + "${PROJECT_SRC}/src/s_ctanhf.c" + "${PROJECT_SRC}/src/s_cacos.c" + "${PROJECT_SRC}/src/s_cacosf.c" + "${PROJECT_SRC}/src/s_cacosh.c" + "${PROJECT_SRC}/src/s_cacoshf.c" + "${PROJECT_SRC}/src/s_casin.c" + "${PROJECT_SRC}/src/s_casinf.c" + "${PROJECT_SRC}/src/s_casinh.c" + "${PROJECT_SRC}/src/s_casinhf.c" + "${PROJECT_SRC}/src/s_catan.c" + "${PROJECT_SRC}/src/s_catanf.c" + "${PROJECT_SRC}/src/s_catanh.c" + "${PROJECT_SRC}/src/s_catanhf.c" + "${PROJECT_SRC}/src/s_clog.c" + "${PROJECT_SRC}/src/s_clogf.c" + + # bsdsrc + "${PROJECT_SRC}/bsdsrc/b_exp.c" + "${PROJECT_SRC}/bsdsrc/b_log.c" + "${PROJECT_SRC}/bsdsrc/b_tgamma.c" +) + +if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/src/s_nan.c" + ) +endif() + +# Determine if long double and double are the same size +include(CheckCSourceCompiles) +check_c_source_compiles(" +#include +#if (LDBL_MANT_DIG == DBL_MANT_DIG) +#error \"long double and double are the same size\" +#endif +int main(void ) { return 0; } +" LONG_DOUBLE_NOT_DOUBLE) + +# Add in long double functions for x86, x64 and aarch64 +if(LONG_DOUBLE_NOT_DOUBLE) + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/src/s_copysignl.c" + "${PROJECT_SRC}/src/s_fabsl.c" + "${PROJECT_SRC}/src/s_llrintl.c" + "${PROJECT_SRC}/src/s_lrintl.c" + "${PROJECT_SRC}/src/s_modfl.c" + + "${PROJECT_SRC}/src/e_acosl.c" + "${PROJECT_SRC}/src/e_asinl.c" + "${PROJECT_SRC}/src/e_atan2l.c" + "${PROJECT_SRC}/src/e_fmodl.c" + "${PROJECT_SRC}/src/s_fmaxl.c" + "${PROJECT_SRC}/src/s_fminl.c" + "${PROJECT_SRC}/src/s_ilogbl.c" + "${PROJECT_SRC}/src/e_hypotl.c" + "${PROJECT_SRC}/src/e_lgammal.c" + "${PROJECT_SRC}/src/e_remainderl.c" + "${PROJECT_SRC}/src/e_sqrtl.c" + "${PROJECT_SRC}/src/s_atanl.c" + "${PROJECT_SRC}/src/s_ceill.c" + "${PROJECT_SRC}/src/s_cosl.c" + "${PROJECT_SRC}/src/s_cprojl.c" + "${PROJECT_SRC}/src/s_csqrtl.c" + "${PROJECT_SRC}/src/s_floorl.c" + "${PROJECT_SRC}/src/s_fmal.c" + "${PROJECT_SRC}/src/s_frexpl.c" + "${PROJECT_SRC}/src/s_logbl.c" + "${PROJECT_SRC}/src/s_nexttoward.c" + "${PROJECT_SRC}/src/s_remquol.c" + "${PROJECT_SRC}/src/s_roundl.c" + "${PROJECT_SRC}/src/s_lroundl.c" + "${PROJECT_SRC}/src/s_llroundl.c" + "${PROJECT_SRC}/src/s_cpowl.c" + "${PROJECT_SRC}/src/s_cargl.c" + "${PROJECT_SRC}/src/s_sinl.c" + "${PROJECT_SRC}/src/s_sincosl.c" + "${PROJECT_SRC}/src/s_tanl.c" + "${PROJECT_SRC}/src/s_truncl.c" + "${PROJECT_SRC}/src/w_cabsl.c" + "${PROJECT_SRC}/src/s_nextafterl.c" + "${PROJECT_SRC}/src/s_rintl.c" + "${PROJECT_SRC}/src/s_scalbnl.c" + "${PROJECT_SRC}/src/polevll.c" + "${PROJECT_SRC}/src/s_casinl.c" + "${PROJECT_SRC}/src/s_ctanl.c" + "${PROJECT_SRC}/src/s_cimagl.c" + "${PROJECT_SRC}/src/s_conjl.c" + "${PROJECT_SRC}/src/s_creall.c" + "${PROJECT_SRC}/src/s_cacoshl.c" + "${PROJECT_SRC}/src/s_catanhl.c" + "${PROJECT_SRC}/src/s_casinhl.c" + "${PROJECT_SRC}/src/s_catanl.c" + "${PROJECT_SRC}/src/s_csinl.c" + "${PROJECT_SRC}/src/s_cacosl.c" + "${PROJECT_SRC}/src/s_cexpl.c" + "${PROJECT_SRC}/src/s_csinhl.c" + "${PROJECT_SRC}/src/s_ccoshl.c" + "${PROJECT_SRC}/src/s_clogl.c" + "${PROJECT_SRC}/src/s_ctanhl.c" + "${PROJECT_SRC}/src/s_ccosl.c" + "${PROJECT_SRC}/src/s_cbrtl.c" + ) +endif() + +if (LONG_DOUBLE_NOT_DOUBLE) + if (${OPENLIBM_ARCH_FOLDER} STREQUAL "i387" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "amd64") + list(APPEND OPENLIBM_C_SOURCE + # ld80 + "${PROJECT_SRC}/ld80/invtrig.c" + "${PROJECT_SRC}/ld80/e_acoshl.c" + "${PROJECT_SRC}/ld80/e_powl.c" + "${PROJECT_SRC}/ld80/k_tanl.c" + "${PROJECT_SRC}/ld80/s_exp2l.c" + "${PROJECT_SRC}/ld80/e_atanhl.c" + "${PROJECT_SRC}/ld80/e_lgammal_r.c" + "${PROJECT_SRC}/ld80/e_sinhl.c" + "${PROJECT_SRC}/ld80/s_asinhl.c" + "${PROJECT_SRC}/ld80/s_expm1l.c" + "${PROJECT_SRC}/ld80/e_coshl.c" + "${PROJECT_SRC}/ld80/e_log10l.c" + "${PROJECT_SRC}/ld80/e_tgammal.c" + "${PROJECT_SRC}/ld80/e_expl.c" + "${PROJECT_SRC}/ld80/e_log2l.c" + "${PROJECT_SRC}/ld80/k_cosl.c" + "${PROJECT_SRC}/ld80/s_log1pl.c" + "${PROJECT_SRC}/ld80/s_tanhl.c" + "${PROJECT_SRC}/ld80/e_logl.c" + "${PROJECT_SRC}/ld80/k_sinl.c" + "${PROJECT_SRC}/ld80/s_erfl.c" + ) + + if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/ld80/s_nanl.c" + ) + endif() + else() + if(${OPENLIBM_ARCH_FOLDER} STREQUAL "aarch64") + list(APPEND OPENLIBM_C_SOURCE + # ld128 + "${PROJECT_SRC}/ld128/invtrig.c" + "${PROJECT_SRC}/ld128/e_acoshl.c" + "${PROJECT_SRC}/ld128/e_powl.c" + "${PROJECT_SRC}/ld128/k_tanl.c" + "${PROJECT_SRC}/ld128/s_exp2l.c" + "${PROJECT_SRC}/ld128/e_atanhl.c" + "${PROJECT_SRC}/ld128/e_lgammal_r.c" + "${PROJECT_SRC}/ld128/e_sinhl.c" + "${PROJECT_SRC}/ld128/s_asinhl.c" + "${PROJECT_SRC}/ld128/s_expm1l.c" + "${PROJECT_SRC}/ld128/e_coshl.c" + "${PROJECT_SRC}/ld128/e_log10l.c" + "${PROJECT_SRC}/ld128/e_tgammal.c" + "${PROJECT_SRC}/ld128/e_expl.c" + "${PROJECT_SRC}/ld128/e_log2l.c" + "${PROJECT_SRC}/ld128/k_cosl.c" + "${PROJECT_SRC}/ld128/s_log1pl.c" + "${PROJECT_SRC}/ld128/s_tanhl.c" + "${PROJECT_SRC}/ld128/e_logl.c" + "${PROJECT_SRC}/ld128/k_sinl.c" + "${PROJECT_SRC}/ld128/s_erfl.c" + ) + + if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/ld128/s_nanl.c" + ) + endif() + endif() + endif() +endif() + +# Architecture-specific sources +if (${OPENLIBM_ARCH_FOLDER} STREQUAL "amd64") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/amd64/fenv.c" + ) + + list(APPEND OPENLIBM_ASM_SOURCE + "${PROJECT_SRC}/amd64/e_remainder.S" + "${PROJECT_SRC}/amd64/e_remainderf.S" + "${PROJECT_SRC}/amd64/e_remainderl.S" + "${PROJECT_SRC}/amd64/e_sqrt.S" + "${PROJECT_SRC}/amd64/e_sqrtf.S" + "${PROJECT_SRC}/amd64/e_sqrtl.S" + "${PROJECT_SRC}/amd64/s_llrint.S" + "${PROJECT_SRC}/amd64/s_llrintf.S" + "${PROJECT_SRC}/amd64/s_llrintl.S" + "${PROJECT_SRC}/amd64/s_logbl.S" + "${PROJECT_SRC}/amd64/s_lrint.S" + "${PROJECT_SRC}/amd64/s_lrintf.S" + "${PROJECT_SRC}/amd64/s_lrintl.S" + "${PROJECT_SRC}/amd64/s_remquo.S" + "${PROJECT_SRC}/amd64/s_remquof.S" + "${PROJECT_SRC}/amd64/s_remquol.S" + "${PROJECT_SRC}/amd64/s_rintl.S" + "${PROJECT_SRC}/amd64/s_scalbn.S" + "${PROJECT_SRC}/amd64/s_scalbnf.S" + "${PROJECT_SRC}/amd64/s_scalbnl.S" + "${PROJECT_SRC}/amd64/e_fmod.S" + "${PROJECT_SRC}/amd64/e_fmodf.S" + "${PROJECT_SRC}/amd64/e_fmodl.S" + ) + +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "aarch64") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/aarch64/fenv.c" + ) + +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "arm") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/${OPENLIBM_ARCH_FOLDER}/fenv.c" + ) + +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "i387") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/i387/fenv.c" + ) + + list(APPEND OPENLIBM_ASM_SOURCE + "${PROJECT_SRC}/i387/e_exp.S" + "${PROJECT_SRC}/i387/e_fmod.S" + "${PROJECT_SRC}/i387/e_log.S" + "${PROJECT_SRC}/i387/e_log10.S" + "${PROJECT_SRC}/i387/e_remainder.S" + "${PROJECT_SRC}/i387/e_sqrt.S" + "${PROJECT_SRC}/i387/s_ceil.S" + "${PROJECT_SRC}/i387/s_copysign.S" + "${PROJECT_SRC}/i387/s_floor.S" + "${PROJECT_SRC}/i387/s_llrint.S" + "${PROJECT_SRC}/i387/s_logb.S" + "${PROJECT_SRC}/i387/s_lrint.S" + "${PROJECT_SRC}/i387/s_remquo.S" + "${PROJECT_SRC}/i387/s_rint.S" + "${PROJECT_SRC}/i387/s_tan.S" + "${PROJECT_SRC}/i387/s_trunc.S" + + # float counterparts + "${PROJECT_SRC}/i387/e_log10f.S" + "${PROJECT_SRC}/i387/e_logf.S" + "${PROJECT_SRC}/i387/e_remainderf.S" + "${PROJECT_SRC}/i387/e_sqrtf.S" + "${PROJECT_SRC}/i387/s_ceilf.S" + "${PROJECT_SRC}/i387/s_copysignf.S" + "${PROJECT_SRC}/i387/s_floorf.S" + "${PROJECT_SRC}/i387/s_llrintf.S" + "${PROJECT_SRC}/i387/s_logbf.S" + "${PROJECT_SRC}/i387/s_lrintf.S" + "${PROJECT_SRC}/i387/s_remquof.S" + "${PROJECT_SRC}/i387/s_rintf.S" + "${PROJECT_SRC}/i387/s_truncf.S" + + # long double counterparts + "${PROJECT_SRC}/i387/e_remainderl.S" + "${PROJECT_SRC}/i387/e_sqrtl.S" + "${PROJECT_SRC}/i387/s_ceill.S" + "${PROJECT_SRC}/i387/s_copysignl.S" + "${PROJECT_SRC}/i387/s_floorl.S" + "${PROJECT_SRC}/i387/s_llrintl.S" + "${PROJECT_SRC}/i387/s_logbl.S" + "${PROJECT_SRC}/i387/s_lrintl.S" + "${PROJECT_SRC}/i387/s_remquol.S" + "${PROJECT_SRC}/i387/s_rintl.S" + "${PROJECT_SRC}/i387/s_truncl.S" + ) + + if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + list(APPEND OPENLIBM_ASM_SOURCE + "${PROJECT_SRC}/i387/s_scalbn.S" + "${PROJECT_SRC}/i387/s_scalbnf.S" + "${PROJECT_SRC}/i387/s_scalbnl.S" + ) + endif() + +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "powerpc") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/powerpc/fenv.c" + ) +elseif(${OPENLIBM_ARCH_FOLDER} STREQUAL "riscv64") + list(APPEND OPENLIBM_C_SOURCE + "${PROJECT_SRC}/riscv64/fenv.c") +else() + message(FATAL_ERROR "${PROJECT_NAME} CMake build is not set up for ${OPENLIBM_ARCH_FOLDER}") +endif() + + +# Filter out C implementation from compilation list if a native implementation exists +foreach(FILE_TO_REMOVE ${OPENLIBM_ASM_SOURCE}) + # Get filename and strip out extension + cmake_path(GET FILE_TO_REMOVE FILENAME FILENAME_TO_REMOVE) + cmake_path(REMOVE_EXTENSION FILENAME_TO_REMOVE OUTPUT_VARIABLE FILENAME_TO_REMOVE) + message(DEBUG "Filename to remove: ${FILENAME_TO_REMOVE}") + + # Go through files and remove one with the same name + foreach(CUR_FILE ${OPENLIBM_C_SOURCE}) + cmake_path(GET CUR_FILE FILENAME CUR_FILENAME) + cmake_path(REMOVE_EXTENSION CUR_FILENAME OUTPUT_VARIABLE CUR_FILENAME) + + if(${CUR_FILENAME} STREQUAL ${FILENAME_TO_REMOVE}) + list(REMOVE_ITEM OPENLIBM_C_SOURCE ${CUR_FILE}) + message(DEBUG "Removed source file from compilation list: ${CUR_FILE}") + break() + endif() + endforeach() +endforeach() + + +# Add sources +target_sources("${PROJECT_NAME}" PRIVATE ${OPENLIBM_C_SOURCE} + ${OPENLIBM_ASM_SOURCE} +) + + +# Include directories +list(APPEND OPENLIBM_INCLUDE_DIRS + "${PROJECT_SRC}" + "${PROJECT_SRC}/include" + "${PROJECT_SRC}/${OPENLIBM_ARCH_FOLDER}" + "${PROJECT_SRC}/src" +) + +if(${OPENLIBM_ARCH_FOLDER} STREQUAL "i387" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "amd64" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "powerpc") + list(APPEND OPENLIBM_INCLUDE_DIRS "${PROJECT_SRC}/ld80") +else() + if(${OPENLIBM_ARCH_FOLDER} STREQUAL "aarch64" OR ${OPENLIBM_ARCH_FOLDER} STREQUAL "riscv64") + list(APPEND OPENLIBM_INCLUDE_DIRS "${PROJECT_SRC}/ld128") + endif() +endif() + +target_include_directories("${PROJECT_NAME}" PUBLIC ${OPENLIBM_INCLUDE_DIRS}) + +file(GLOB PUBLIC_HEADERS "*.h" "include/*.h" "${OPENLIBM_ARCH_FOLDER}/*.h" "src/*.h") +set_target_properties("${PROJECT_NAME}" PROPERTIES PUBLIC_HEADER "${PUBLIC_HEADERS}") +install (TARGETS "${PROJECT_NAME}") + +# Can't use configure_file because openlibm.pc.in uses $var instead of CMake configure @var's +# Would rather string replace variables here instead of editing .pc.in, because editing .pc.in +# might build break autotools build. +file(READ "${PROJECT_SRC}/openlibm.pc.in" PC_FILE) +string(REPLACE "\${version}" ${CMAKE_PROJECT_VERSION} PC_FILE ${PC_FILE}) +string(PREPEND PC_FILE "prefix=${CMAKE_INSTALL_PREFIX} +includedir=\${prefix}/${CMAKE_INSTALL_INCLUDEDIR} +libdir=\${prefix}/${CMAKE_INSTALL_LIBDIR}\n +") +file(WRITE "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc" ${PC_FILE}) +install(FILES "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc" + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") diff --git a/openlibm/LICENSE.md b/openlibm/LICENSE.md index 869ae163..d76019ef 100644 --- a/openlibm/LICENSE.md +++ b/openlibm/LICENSE.md @@ -16,7 +16,7 @@ are under the LGPL. ## Parts copyrighted by the Julia project (MIT License) > Copyright (c) 2011-14 The Julia Project. -> https://github.com/JuliaLang/openlibm/graphs/contributors +> https://github.com/JuliaMath/openlibm/graphs/contributors > > Permission is hereby granted, free of charge, to any person obtaining > a copy of this software and associated documentation files (the diff --git a/openlibm/Make.inc b/openlibm/Make.inc index f1c177d1..7914e821 100644 --- a/openlibm/Make.inc +++ b/openlibm/Make.inc @@ -1,4 +1,5 @@ # -*- mode: makefile-gmake -*- +# vi:ft=make # Default build rule for any Makefile in this project: all default: all @@ -6,30 +7,50 @@ default: all OS := $(shell uname) # Do not forget to bump SOMINOR when changing VERSION, # and SOMAJOR when breaking ABI in a backward-incompatible way -VERSION = 0.5.5 -SOMAJOR = 2 -SOMINOR = 4 +VERSION = 0.8.0 +SOMAJOR = 4 +SOMINOR = 0 DESTDIR = -prefix = /usr/local -bindir = $(prefix)/bin -libdir = $(prefix)/lib -includedir = $(prefix)/include +prefix ?= /usr/local +bindir ?= $(prefix)/bin +libdir ?= $(prefix)/lib +includedir ?= $(prefix)/include ifeq ($(OS), FreeBSD) -pkgconfigdir = $(prefix)/libdata/pkgconfig +pkgconfigdir ?= $(prefix)/libdata/pkgconfig else -pkgconfigdir = $(libdir)/pkgconfig +pkgconfigdir ?= $(libdir)/pkgconfig endif -USEGCC = 1 -USECLANG = 0 +# Build with Code Coverage +# Only test with Ubuntu + gcc + lcov, may not work for other platform. +# deps: https://github.com/linux-test-project/lcov +# You don't need to set this flag manually, `make coverage` will do it for you. +# Just Run: make clean && make coverage -j +CODE_COVERAGE ?= 0 ifneq (,$(findstring $(OS),Darwin FreeBSD OpenBSD)) +USEGCC ?= 0 +USECLANG ?= 1 +endif + +ifneq (,$(findstring CLANG,$(MSYSTEM))) +# In MSYS2 USEGCC = 0 USECLANG = 1 endif -AR = ar +ifeq ($(ARCH),wasm32) +USECLANG = 1 +USEGCC = 0 +TOOLPREFIX = llvm- +endif + +USEGCC ?= 1 +USECLANG ?= 0 +TOOLPREFIX ?= + +AR := $(TOOLPREFIX)ar ifeq ($(USECLANG),1) USEGCC = 0 @@ -38,7 +59,7 @@ CFLAGS_add += -fno-builtin -fno-strict-aliasing endif ifeq ($(USEGCC),1) -CC = gcc +CC := $(TOOLPREFIX)gcc CFLAGS_add += -fno-gnu89-inline -fno-builtin endif @@ -49,9 +70,12 @@ $(error "the mingw32 compiler you are using fails the openblas testsuite. please endif # OS-specific stuff +ifeq ($(ARCH),arm64) +override ARCH := aarch64 +endif ifeq ($(findstring arm,$(ARCH)),arm) override ARCH := arm -MARCH ?= armv7-a +MARCH ?= armv7-a+fp CFLAGS_add += -mhard-float endif ifeq ($(findstring powerpc,$(ARCH)),powerpc) @@ -60,6 +84,9 @@ endif ifeq ($(findstring ppc,$(ARCH)),ppc) override ARCH := powerpc endif +ifeq ($(findstring s390,$(ARCH)),s390) +override ARCH := s390 +endif ifneq ($(filter $(ARCH),i386 i486 i586 i686 i387 i487 i587 i687),) override ARCH := i387 MARCH ?= i686 @@ -67,6 +94,15 @@ endif ifeq ($(ARCH),x86_64) override ARCH := amd64 endif +ifeq ($(findstring mips,$(ARCH)),mips) +override ARCH := mips +endif +ifeq ($(findstring riscv64,$(ARCH)),riscv64) +override ARCH := riscv64 +endif +ifeq ($(findstring loongarch64,$(ARCH)),loongarch64) +override ARCH := loongarch64 +endif # If CFLAGS does not contain a -O optimization flag, default to -O3 ifeq ($(findstring -O,$(CFLAGS)),) @@ -80,8 +116,7 @@ endif #keep these if statements separate ifeq ($(OS), WINNT) SHLIB_EXT = dll -SONAME_FLAG = -soname -CFLAGS_add += -nodefaultlibs +SONAME_FLAG = shlibdir = $(bindir) else ifeq ($(OS), Darwin) @@ -112,6 +147,10 @@ SFLAGS_arch += -m64 LDFLAGS_arch += -m64 endif +ifeq ($(ARCH),wasm32) +CFLAGS_arch += -ffreestanding -nostdlib -nostdinc --target=wasm32-unknown-unknown +endif + # Add our "arch"-related FLAGS in. We separate arch-related flags out so that # we can conveniently get at them for targets that don't want the rest of # *FLAGS_add, such as the testing Makefile targets @@ -123,18 +162,27 @@ CFLAGS_add += -std=c99 -Wall -I$(OPENLIBM_HOME) -I$(OPENLIBM_HOME)/include -I$(O ifneq ($(filter $(ARCH),i387 amd64 powerpc),) CFLAGS_add += -I$(OPENLIBM_HOME)/ld80 else -ifneq ($(filter $(ARCH),aarch64),) +ifneq ($(filter $(ARCH),aarch64 riscv64),) CFLAGS_add += -I$(OPENLIBM_HOME)/ld128 endif endif +ifneq ($(filter $(ARCH),i387 amd64),) +# Determines whether `long double` is the same as `double` on this arch. +# linux x86_64, for instance, `long double` is 80 bits wide, whereas on macOS aarch64, +# `long double` is the same as `double`. +LONG_DOUBLE_NOT_DOUBLE := 1 +else ifeq ($(ARCH), aarch64) +ifeq ($(filter $(OS),Darwin WINNT),) +LONG_DOUBLE_NOT_DOUBLE := 1 +endif +endif -# *int / *intf need to be built with -O0 -src/%int.c.o: src/%int.c - $(CC) $(CPPFLAGS) -O0 $(CFLAGS_add) -c $< -o $@ +ifeq ($(CODE_COVERAGE),1) +CFLAGS_add += -g -O0 --coverage +LDFLAGS_add += --coverage +endif # CODE_COVERAGE==1 -src/%intf.c.o: src/%intf.c - $(CC) $(CPPFLAGS) -O0 $(CFLAGS_add) -c $< -o $@ %.c.o: %.c $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_add) -c $< -o $@ diff --git a/openlibm/Makefile b/openlibm/Makefile index 7144cf9f..0d7d9185 100644 --- a/openlibm/Makefile +++ b/openlibm/Makefile @@ -2,6 +2,7 @@ OPENLIBM_HOME=$(abspath .) include ./Make.inc SUBDIRS = src $(ARCH) bsdsrc +ifeq ($(LONG_DOUBLE_NOT_DOUBLE),1) # Add ld80 directory on x86 and x64 ifneq ($(filter $(ARCH),i387 amd64),) SUBDIRS += ld80 @@ -11,6 +12,7 @@ SUBDIRS += ld128 else endif endif +endif define INC_template TEST=test @@ -44,12 +46,19 @@ else OLM_MAJOR_MINOR_SHLIB_EXT := $(SHLIB_EXT).$(SOMAJOR).$(SOMINOR) OLM_MAJOR_SHLIB_EXT := $(SHLIB_EXT).$(SOMAJOR) endif +LDFLAGS_add += -Wl,$(SONAME_FLAG),libopenlibm.$(OLM_MAJOR_SHLIB_EXT) endif .PHONY: all check test clean distclean \ install install-static install-shared install-pkgconfig install-headers -all: libopenlibm.a libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT) + +OLM_LIBS := libopenlibm.a +ifneq ($(ARCH), wasm32) +OLM_LIBS += libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT) +endif + +all : $(OLM_LIBS) check test: test/test-double test/test-float test/test-double @@ -59,7 +68,7 @@ libopenlibm.a: $(OBJS) $(AR) -rcs libopenlibm.a $(OBJS) libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT): $(OBJS) - $(CC) -shared $(OBJS) $(LDFLAGS) $(LDFLAGS_add) -Wl,$(SONAME_FLAG),libopenlibm.$(OLM_MAJOR_SHLIB_EXT) -o $@ + $(CC) -shared $(OBJS) $(LDFLAGS) $(LDFLAGS_add) -o $@ ifneq ($(OS),WINNT) ln -sf $@ libopenlibm.$(OLM_MAJOR_SHLIB_EXT) ln -sf $@ libopenlibm.$(SHLIB_EXT) @@ -71,14 +80,38 @@ test/test-double: libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT) test/test-float: libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT) $(MAKE) -C test test-float -clean: - rm -f aarch64/*.o amd64/*.o arm/*.o bsdsrc/*.o i387/*.o ld80/*.o ld128/*.o src/*.o powerpc/*.o +COVERAGE_DIR:=cov-html +COVERAGE_FILE:=$(COVERAGE_DIR)/libopenlibm.info +# Gen cov report with: make clean && make coverage -j +coverage: clean-coverage + $(MAKE) test CODE_COVERAGE=1 + $(MAKE) gen-cov-report + +gen-cov-report: + -mkdir $(COVERAGE_DIR) + lcov -d amd64 -d bsdsrc -d ld80 -d src \ + --rc lcov_branch_coverage=1 --capture --output-file $(COVERAGE_FILE) + genhtml --legend --branch-coverage \ + --title "Openlibm commit `git rev-parse HEAD`" \ + --output-directory $(COVERAGE_DIR)/ \ + $(COVERAGE_FILE) + +# Zero coverage statistics and Delete report +clean-coverage: + -lcov -d amd64 -d bsdsrc -d ld80 -d src --zerocounters + rm -f ./*/*.gcda + rm -rf $(COVERAGE_DIR)/ + +clean: clean-coverage + rm -f aarch64/*.o amd64/*.o arm/*.o bsdsrc/*.o i387/*.o loongarch64/*.o ld80/*.o ld128/*.o src/*.o powerpc/*.o mips/*.o s390/*.o riscv64/*.o rm -f libopenlibm.a libopenlibm.*$(SHLIB_EXT)* + rm -f ./*/*.gcno $(MAKE) -C test clean openlibm.pc: openlibm.pc.in Make.inc Makefile - echo "prefix=${prefix}" > openlibm.pc - echo "version=${VERSION}" >> openlibm.pc + echo "version=${VERSION}" > openlibm.pc + echo "libdir=$(DESTDIR)$(libdir)" >> openlibm.pc + echo "includedir=$(DESTDIR)$(includedir)/openlibm" >> openlibm.pc cat openlibm.pc.in >> openlibm.pc install-static: libopenlibm.a @@ -87,7 +120,13 @@ install-static: libopenlibm.a install-shared: libopenlibm.$(OLM_MAJOR_MINOR_SHLIB_EXT) mkdir -p $(DESTDIR)$(shlibdir) +ifeq ($(OS), WINNT) + mkdir -p $(DESTDIR)$(libdir) + cp -RpP -f libopenlibm.*$(SHLIB_EXT) $(DESTDIR)$(shlibdir)/ + cp -RpP -f libopenlibm.*$(SHLIB_EXT).a $(DESTDIR)$(libdir)/ +else cp -RpP -f libopenlibm.*$(SHLIB_EXT)* $(DESTDIR)$(shlibdir)/ +endif install-pkgconfig: openlibm.pc mkdir -p $(DESTDIR)$(pkgconfigdir) diff --git a/openlibm/README.md b/openlibm/README.md index 81d2e964..d543a3bc 100644 --- a/openlibm/README.md +++ b/openlibm/README.md @@ -1,36 +1,71 @@ # OpenLibm -[![Build Status](https://travis-ci.org/JuliaLang/openlibm.svg?branch=master)](https://travis-ci.org/JuliaLang/openlibm) +[![codecov](https://codecov.io/gh/JuliaMath/openlibm/graph/badge.svg?token=eTAdN7d9cg)](https://codecov.io/gh/JuliaMath/openlibm) -[OpenLibm](http://www.openlibm.org) is an effort to have a high quality, portable, standalone +[OpenLibm](https://openlibm.org/) is an effort to have a high quality, portable, standalone C mathematical library ([`libm`](http://en.wikipedia.org/wiki/libm)). It can be used standalone in applications and programming language implementations. The project was born out of a need to have a good `libm` for the -[Julia programming langage](http://www.julialang.org) that worked +[Julia programming language](http://www.julialang.org) that worked consistently across compilers and operating systems, and in 32-bit and 64-bit environments. ## Platform support -OpenLibm builds on Linux, Mac OS X, Windows, FreeBSD, OpenBSD, and DragonFly BSD. -It builds with both GCC and clang. Although largely tested and widely -used on x86 architectures, OpenLibm also supports ARM and -PowerPC. +OpenLibm builds on Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD, and +DragonFly BSD. It builds with both GCC and clang. Although largely +tested and widely used on the x86 and x86-64 architectures, OpenLibm +also supports arm, aarch64, ppc64le, mips, wasm32, riscv, s390(x) and +loongarch64. ## Build instructions +### GNU Make + 1. Use GNU Make to build OpenLibm. This is `make` on most systems, but `gmake` on BSDs. 2. Use `make USEGCC=1` to build with GCC. This is the default on Linux and Windows. 3. Use `make USECLANG=1` to build with clang. This is the default on OS X, FreeBSD, and OpenBSD. -4. Architectures are auto-detected. Use `make ARCH=i386` to force a +4. Use `make ARCH=wasm32` to build the wasm32 library with clang. +5. Architectures are auto-detected. Use `make ARCH=i386` to force a build for i386. Other supported architectures are i486, i586, and i686. GCC 4.8 is the minimum requirement for correct codegen on older 32-bit architectures. + +**Cross Build** +Take `riscv64` as example: +1. install `qemu-riscv64-static`, `gcc-riscv64-linux-gnu` +2. Cross build: +```sh +ARCH=riscv64 +TRIPLE=$ARCH-linux-gnu +make ARCH=$ARCH TOOLPREFIX=$TRIPLE- -j +make -C test ARCH=$ARCH TOOLPREFIX=$TRIPLE- -j +``` + +3. Run test with qemu: +```sh +qemu-$ARCH-static -L . -L /usr/$TRIPLE/ test/test-float +qemu-$ARCH-static -L . -L /usr/$TRIPLE/ test/test-double +``` + + +### CMake + +1. Create build directory with `mkdir build` and navigate into it with `cd build`. +2. Run CMake to configure project and generate native build system with `cmake /path/to/openlibm/` +or generate project with build system of choice e.g. `cmake /path/to/openlib/ -G "MinGW Makefiles"`. +3. Build with the build system with `cmake --build .`. + +Default CMake configuration builds a shared library, this can easily be configured using +[BUILD_SHARED_LIBS](https://cmake.org/cmake/help/latest/variable/BUILD_SHARED_LIBS.html) +configuration option. + + ## Acknowledgements PowerPC support for openlibm was graciously sponsored by IBM. diff --git a/openlibm/aarch64/fenv.c b/openlibm/aarch64/fenv.c index c9abf145..8ed85576 100644 --- a/openlibm/aarch64/fenv.c +++ b/openlibm/aarch64/fenv.c @@ -26,7 +26,6 @@ * $FreeBSD: src/lib/msun/arm/fenv.c,v 1.3 2011/10/16 05:37:56 das Exp $ */ -#define __fenv_static #include #ifdef __GNUC_GNU_INLINE__ @@ -37,7 +36,7 @@ * Hopefully the system ID byte is immutable, so it's valid to use * this as a default environment. */ -const fenv_t __fe_dfl_env = 0; +const fenv_t __fe_dfl_env = {0}; extern inline int feclearexcept(int __excepts); extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); diff --git a/openlibm/amd64/Make.files b/openlibm/amd64/Make.files index 6dc21c67..662071c7 100644 --- a/openlibm/amd64/Make.files +++ b/openlibm/amd64/Make.files @@ -3,4 +3,5 @@ $(CUR_SRCS) = fenv.c e_remainder.S e_remainderf.S e_remainderl.S \ s_llrint.S s_llrintf.S s_llrintl.S \ s_logbl.S s_lrint.S s_lrintf.S s_lrintl.S \ s_remquo.S s_remquof.S s_remquol.S \ - s_rintl.S s_scalbn.S s_scalbnf.S s_scalbnl.S + s_rintl.S s_scalbn.S s_scalbnf.S s_scalbnl.S \ + e_fmod.S e_fmodf.S e_fmodl.S diff --git a/openlibm/amd64/e_fmod.S b/openlibm/amd64/e_fmod.S new file mode 100644 index 00000000..d2c8ecd9 --- /dev/null +++ b/openlibm/amd64/e_fmod.S @@ -0,0 +1,56 @@ +/* + * Copyright (c) 1993,94 Winning Strategies, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Winning Strategies, Inc. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Based on the i387 version written by: + * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc. + */ + +#include + +ENTRY(fmod) + movsd %xmm0,-8(%rsp) + movsd %xmm1,-16(%rsp) + fldl -16(%rsp) + fldl -8(%rsp) +1: fprem + fstsw %ax + testw $0x400,%ax + jne 1b + fstpl -8(%rsp) + movsd -8(%rsp),%xmm0 + fstp %st + ret +END(fmod) + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/openlibm/amd64/e_fmodf.S b/openlibm/amd64/e_fmodf.S new file mode 100644 index 00000000..b045e735 --- /dev/null +++ b/openlibm/amd64/e_fmodf.S @@ -0,0 +1,26 @@ +/* + * Based on the i387 version written by J.T. Conklin . + * Public domain. + */ + +#include + +ENTRY(fmodf) + movss %xmm0,-4(%rsp) + movss %xmm1,-8(%rsp) + flds -8(%rsp) + flds -4(%rsp) +1: fprem + fstsw %ax + testw $0x400,%ax + jne 1b + fstps -4(%rsp) + movss -4(%rsp),%xmm0 + fstp %st + ret +END(fmodf) + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/openlibm/amd64/e_fmodl.S b/openlibm/amd64/e_fmodl.S new file mode 100644 index 00000000..cab539d5 --- /dev/null +++ b/openlibm/amd64/e_fmodl.S @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1993,94 Winning Strategies, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Winning Strategies, Inc. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Based on the i387 version written by: + * J.T. Conklin (jtc@wimsey.com), Winning Strategies, Inc. + */ + +#include + +ENTRY(fmodl) + fldt 24(%rsp) + fldt 8(%rsp) +1: fprem + fstsw %ax + testw $0x400,%ax + jne 1b + fstp %st(1) + ret +END(fmodl) + +/* Enable stack protection */ +#if defined(__ELF__) +.section .note.GNU-stack,"",%progbits +#endif diff --git a/openlibm/bsdsrc/b_tgamma.c b/openlibm/bsdsrc/b_tgamma.c index 7f5f0945..f3871ded 100644 --- a/openlibm/bsdsrc/b_tgamma.c +++ b/openlibm/bsdsrc/b_tgamma.c @@ -38,6 +38,7 @@ * acknowledged. */ +#include #include #include "mathimpl.h" @@ -312,3 +313,7 @@ neg_gam(x) if (sgn < 0) y = -y; return (M_PI / (y*z)); } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(tgamma, tgammal); +#endif diff --git a/openlibm/docs/CNAME b/openlibm/docs/CNAME new file mode 100644 index 00000000..60f23f5b --- /dev/null +++ b/openlibm/docs/CNAME @@ -0,0 +1 @@ +openlibm.org \ No newline at end of file diff --git a/openlibm/docs/images/arrow-down.png b/openlibm/docs/images/arrow-down.png new file mode 100644 index 00000000..5c55c6a8 Binary files /dev/null and b/openlibm/docs/images/arrow-down.png differ diff --git a/openlibm/docs/images/octocat-small.png b/openlibm/docs/images/octocat-small.png new file mode 100644 index 00000000..57c1e44f Binary files /dev/null and b/openlibm/docs/images/octocat-small.png differ diff --git a/openlibm/docs/index.html b/openlibm/docs/index.html new file mode 100644 index 00000000..5c84d7e6 --- /dev/null +++ b/openlibm/docs/index.html @@ -0,0 +1,94 @@ + + + + + + OpenLibm + + + + + + + +
+
+

OpenLibm

+

A high quality system independent, portable, open source libm implementation

+ + + +

This project is maintained by the Julia Project

+ + +
+
+

+OpenLibm

+ +

OpenLibm is an effort to have a high quality, portable, standalone +C mathematical library (libm). +It can be used standalone in applications and programming language +implementations.

+ +

The project was born out of a need to have a good libm for the +Julia programming langage that worked +consistently across compilers and operating systems, and in 32-bit and +64-bit environments.

+ +

+History

+ +

The OpenLibm code derives from the FreeBSD +msun and OpenBSD +libm +implementations, which in turn derive from FDLIBM +5.3. Over and above that, OpenLibm itself has received a number of patches to make it platform independent and portable.

+ +

+Platform support

+ +

OpenLibm builds on Linux, macOS, Windows, FreeBSD, OpenBSD, NetBSD, and +DragonFly BSD. It builds with both GCC and clang. OpenLibm supports x86, amd64, +arm, aarch64, riscv64, ppc64le, mips, wasm32, s390(x), and loongarch64. + +

+Other relevant projects

+ +
    +
  1. MUSL The libm library in the musl-libc project
  2. +
  3. FDLIBM: Freely Distributable Math Library
  4. +
  5. FreeBSD msun: FreeBSD's math library
  6. +
  7. CRlibm: Correctly Rounded mathematical library
  8. +
  9. MUSL
  10. +
  11. CORE-MATH Project
  12. +
+ +

+Acknowledgements

+ +

PowerPC support for OpenLibm was graciously sponsored by IBM. + + +

+ +
+ + + + + + diff --git a/openlibm/docs/javascripts/scale.fix.js b/openlibm/docs/javascripts/scale.fix.js new file mode 100644 index 00000000..08716c00 --- /dev/null +++ b/openlibm/docs/javascripts/scale.fix.js @@ -0,0 +1,20 @@ +fixScale = function(doc) { + + var addEvent = 'addEventListener', + type = 'gesturestart', + qsa = 'querySelectorAll', + scales = [1, 1], + meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : []; + + function fix() { + meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1]; + doc.removeEventListener(type, fix, true); + } + + if ((meta = meta[meta.length - 1]) && addEvent in doc) { + fix(); + scales = [.25, 1.6]; + doc[addEvent](type, fix, true); + } + +}; \ No newline at end of file diff --git a/openlibm/docs/params.json b/openlibm/docs/params.json new file mode 100644 index 00000000..cd0a5ed4 --- /dev/null +++ b/openlibm/docs/params.json @@ -0,0 +1 @@ +{"name":"OpenLibm","tagline":"A high quality system independent, portable, open source libm implementation","body":"## OpenLibm\r\n\r\n[OpenLibm](http://www.openlibm.org) is an effort to have a high quality, portable, standalone\r\nC mathematical library ([`libm`](http://en.wikipedia.org/wiki/libm)).\r\nIt can be used standalone in applications and programming language\r\nimplementations.\r\n\r\nThe project was born out of a need to have a good `libm` for the\r\n[Julia programming langage](http://www.julialang.org) that worked\r\nconsistently across compilers and operating systems, and in 32-bit and\r\n64-bit environments.\r\n\r\n### History\r\n\r\nThe OpenLibm code derives from the [FreeBSD\r\nmsun](http://svnweb.freebsd.org/base/head/lib/msun/) and [OpenBSD\r\nlibm](http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/lib/libm/src/)\r\nimplementations, which in turn derives from [FDLIBM\r\n5.3](http://www.netlib.org/fdlibm/). As a result, it includes a number\r\nof fixes and updates to FDLIBM that have accumulated over the years in\r\n`msun`, and optimized versions of many functions.\r\n\r\n### Platform support\r\n\r\nOpenLibm builds on Linux, Mac OS X, and Windows, and with little\r\neffort, should build on FreeBSD as well. It builds with both GCC and\r\nclang. Although largely tested on x86, it also includes experimental\r\nsupport for ARM. The original `msun` also includes support for mips,\r\nsparc64, powerpc, ia64, and alpha. These are present in the OpenLibm\r\nsource tree, but no attempt has been made to build any of these.\r\n\r\n### Build instructions\r\n\r\n1. `make` or `make USEGCC=1` to build with GCC. This is the default on\r\n Linux and Windows.\r\n2. `make USECLANG=1` to build with clang. This is the default on OS X.\r\n","google":"UA-28835595-4","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file diff --git a/openlibm/docs/stylesheets/pygment_trac.css b/openlibm/docs/stylesheets/pygment_trac.css new file mode 100644 index 00000000..c6a6452d --- /dev/null +++ b/openlibm/docs/stylesheets/pygment_trac.css @@ -0,0 +1,69 @@ +.highlight { background: #ffffff; } +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .o { font-weight: bold } /* Operator */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #d14 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #0086B3 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #d14 } /* Literal.String.Backtick */ +.highlight .sc { color: #d14 } /* Literal.String.Char */ +.highlight .sd { color: #d14 } /* Literal.String.Doc */ +.highlight .s2 { color: #d14 } /* Literal.String.Double */ +.highlight .se { color: #d14 } /* Literal.String.Escape */ +.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ +.highlight .si { color: #d14 } /* Literal.String.Interpol */ +.highlight .sx { color: #d14 } /* Literal.String.Other */ +.highlight .sr { color: #009926 } /* Literal.String.Regex */ +.highlight .s1 { color: #d14 } /* Literal.String.Single */ +.highlight .ss { color: #990073 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ + +.type-csharp .highlight .k { color: #0000FF } +.type-csharp .highlight .kt { color: #0000FF } +.type-csharp .highlight .nf { color: #000000; font-weight: normal } +.type-csharp .highlight .nc { color: #2B91AF } +.type-csharp .highlight .nn { color: #000000 } +.type-csharp .highlight .s { color: #A31515 } +.type-csharp .highlight .sc { color: #A31515 } diff --git a/openlibm/docs/stylesheets/styles.css b/openlibm/docs/stylesheets/styles.css new file mode 100644 index 00000000..647f08db --- /dev/null +++ b/openlibm/docs/stylesheets/styles.css @@ -0,0 +1,423 @@ +@import url(https://fonts.googleapis.com/css?family=Arvo:400,700,400italic); + +/* MeyerWeb Reset */ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font: inherit; + vertical-align: baseline; +} + + +/* Base text styles */ + +body { + padding:10px 50px 0 0; + font-family:"Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + color: #232323; + background-color: #FBFAF7; + margin: 0; + line-height: 1.8em; + -webkit-font-smoothing: antialiased; + +} + +h1, h2, h3, h4, h5, h6 { + color:#232323; + margin:36px 0 10px; +} + +p, ul, ol, table, dl { + margin:0 0 22px; +} + +h1, h2, h3 { + font-family: Arvo, Monaco, serif; + line-height:1.3; + font-weight: normal; +} + +h1,h2, h3 { + display: block; + border-bottom: 1px solid #ccc; + padding-bottom: 5px; +} + +h1 { + font-size: 30px; +} + +h2 { + font-size: 24px; +} + +h3 { + font-size: 18px; +} + +h4, h5, h6 { + font-family: Arvo, Monaco, serif; + font-weight: 700; +} + +a { + color:#C30000; + font-weight:200; + text-decoration:none; +} + +a:hover { + text-decoration: underline; +} + +a small { + font-size: 12px; +} + +em { + font-style: italic; +} + +strong { + font-weight:700; +} + +ul { + list-style-position: inside; + list-style: disc; + padding-left: 25px; +} + +ol { + list-style-position: inside; + list-style: decimal; + padding-left: 25px; +} + +blockquote { + margin: 0; + padding: 0 0 0 20px; + font-style: italic; +} + +dl, dt, dd, dl p { + font-color: #444; +} + +dl dt { + font-weight: bold; +} + +dl dd { + padding-left: 20px; + font-style: italic; +} + +dl p { + padding-left: 20px; + font-style: italic; +} + +hr { + border:0; + background:#ccc; + height:1px; + margin:0 0 24px; +} + +/* Images */ + +img { + position: relative; + margin: 0 auto; + max-width: 650px; + padding: 5px; + margin: 10px 0 32px 0; + border: 1px solid #ccc; +} + +p img { + display: inline; + margin: 0; + padding: 0; + vertical-align: middle; + text-align: center; + border: none; +} + +/* Code blocks */ + +code, pre { + font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; + color:#000; + font-size:14px; +} + +pre { + padding: 4px 12px; + background: #FDFEFB; + border-radius:4px; + border:1px solid #D7D8C8; + overflow: auto; + overflow-y: hidden; + margin-bottom: 32px; +} + + +/* Tables */ + +table { + width:100%; +} + +table { + border: 1px solid #ccc; + margin-bottom: 32px; + text-align: left; + } + +th { + font-family: 'Arvo', Helvetica, Arial, sans-serif; + font-size: 18px; + font-weight: normal; + padding: 10px; + background: #232323; + color: #FDFEFB; + } + +td { + padding: 10px; + background: #ccc; + } + + +/* Wrapper */ +.wrapper { + width:960px; +} + + +/* Header */ + +header { + background-color: #171717; + color: #FDFDFB; + width:170px; + float:left; + position:fixed; + border: 1px solid #000; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + padding: 34px 25px 22px 50px; + margin: 30px 25px 0 0; + -webkit-font-smoothing: antialiased; +} + +p.header { + font-size: 16px; +} + +h1.header { + font-family: Arvo, sans-serif; + font-size: 30px; + font-weight: 300; + line-height: 1.3em; + border-bottom: none; + margin-top: 0; +} + + +h1.header, a.header, a.name, header a{ + color: #fff; +} + +a.header { + text-decoration: underline; +} + +a.name { + white-space: nowrap; +} + +header ul { + list-style:none; + padding:0; +} + +header li { + list-style-type: none; + width:132px; + height:15px; + margin-bottom: 12px; + line-height: 1em; + padding: 6px 6px 6px 7px; + + background: #AF0011; + background: -moz-linear-gradient(top, #AF0011 0%, #820011 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); + background: -webkit-linear-gradient(top, #AF0011 0%,#820011 100%); + background: -o-linear-gradient(top, #AF0011 0%,#820011 100%); + background: -ms-linear-gradient(top, #AF0011 0%,#820011 100%); + background: linear-gradient(top, #AF0011 0%,#820011 100%); + + border-radius:4px; + border:1px solid #0D0D0D; + + -webkit-box-shadow: inset 0px 1px 1px 0 rgba(233,2,38, 1); + box-shadow: inset 0px 1px 1px 0 rgba(233,2,38, 1); + +} + +header li:hover { + background: #C3001D; + background: -moz-linear-gradient(top, #C3001D 0%, #950119 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); + background: -webkit-linear-gradient(top, #C3001D 0%,#950119 100%); + background: -o-linear-gradient(top, #C3001D 0%,#950119 100%); + background: -ms-linear-gradient(top, #C3001D 0%,#950119 100%); + background: linear-gradient(top, #C3001D 0%,#950119 100%); +} + +a.buttons { + -webkit-font-smoothing: antialiased; + background: url(../images/arrow-down.png) no-repeat; + font-weight: normal; + text-shadow: rgba(0, 0, 0, 0.4) 0 -1px 0; + padding: 2px 2px 2px 22px; + height: 30px; +} + +a.github { + background: url(../images/octocat-small.png) no-repeat 1px; +} + +a.buttons:hover { + color: #fff; + text-decoration: none; +} + + +/* Section - for main page content */ + +section { + width:650px; + float:right; + padding-bottom:50px; +} + + +/* Footer */ + +footer { + width:170px; + float:left; + position:fixed; + bottom:10px; + padding-left: 50px; +} + +@media print, screen and (max-width: 960px) { + + div.wrapper { + width:auto; + margin:0; + } + + header, section, footer { + float:none; + position:static; + width:auto; + } + + footer { + border-top: 1px solid #ccc; + margin:0 84px 0 50px; + padding:0; + } + + header { + padding-right:320px; + } + + section { + padding:20px 84px 20px 50px; + margin:0 0 20px; + } + + header a small { + display:inline; + } + + header ul { + position:absolute; + right:130px; + top:84px; + } +} + +@media print, screen and (max-width: 720px) { + body { + word-wrap:break-word; + } + + header { + padding:10px 20px 0; + margin-right: 0; + } + + section { + padding:10px 0 10px 20px; + margin:0 0 30px; + } + + footer { + margin: 0 0 0 30px; + } + + header ul, header p.view { + position:static; + } +} + +@media print, screen and (max-width: 480px) { + + header ul li.download { + display:none; + } + + footer { + margin: 0 0 0 20px; + } + + footer a{ + display:block; + } + +} + +@media print { + body { + padding:0.4in; + font-size:12pt; + color:#444; + } +} \ No newline at end of file diff --git a/openlibm/i387/e_sqrt.S b/openlibm/i387/e_sqrt.S index 7c36dfe5..5cd45b09 100644 --- a/openlibm/i387/e_sqrt.S +++ b/openlibm/i387/e_sqrt.S @@ -8,12 +8,29 @@ //__FBSDID("$FreeBSD: src/lib/msun/i387/e_sqrt.S,v 1.10 2011/01/07 16:13:12 kib Exp $") ENTRY(sqrt) - fldl 4(%esp) + pushl %ebp + movl %esp,%ebp + subl $8,%esp + + fstcw -4(%ebp) /* store fpu control word */ + movw -4(%ebp),%dx + andw $0xfeff,%dx /* Set precision field to 64 bits (53 bit mantissa). + We assume it's set to 0b11 (extended precision), + so zeroing out the low bit of the precision field, + will correctly set the precision */ + movw %dx,-8(%ebp) + fldcw -8(%ebp) /* load modfied control word */ + + fldl 8(%ebp) fsqrt + + fldcw -4(%ebp) /* restore original control word */ + + leave ret END(sqrt) - + /* Enable stack protection */ #if defined(__ELF__) .section .note.GNU-stack,"",%progbits diff --git a/openlibm/include/openlibm_defs.h b/openlibm/include/openlibm_defs.h new file mode 100644 index 00000000..8a6fa6b5 --- /dev/null +++ b/openlibm/include/openlibm_defs.h @@ -0,0 +1,14 @@ +#ifndef OPENLIBM_DEFS_H_ +#define OPENLIBM_DEFS_H_ + +#ifdef _WIN32 +# ifdef IMPORT_EXPORTS +# define OLM_DLLEXPORT __declspec(dllimport) +# else +# define OLM_DLLEXPORT __declspec(dllexport) +# endif +#else +#define OLM_DLLEXPORT __attribute__ ((visibility("default"))) +#endif + +#endif // OPENLIBM_DEFS_H_ diff --git a/openlibm/include/openlibm_fenv.h b/openlibm/include/openlibm_fenv.h index 9cdb4a22..35a5586f 100644 --- a/openlibm/include/openlibm_fenv.h +++ b/openlibm/include/openlibm_fenv.h @@ -2,14 +2,24 @@ #include #else /* !OPENLIBM_USE_HOST_FENV_H */ -#if defined(__aarch64__) || defined(__arm__) +#if defined(__aarch64__) +#include +#elif defined(__arm__) #include #elif defined(__x86_64__) #include #elif defined(__i386__) #include -#elif defined(__powerpc__) +#elif defined(__powerpc__) || defined(__POWERPC__) #include +#elif defined(__mips__) +#include +#elif defined(__s390__) +#include +#elif defined(__riscv) +#include +#elif defined(__loongarch64) +#include #else #error "Unsupported platform" #endif diff --git a/openlibm/include/openlibm_fenv_aarch64.h b/openlibm/include/openlibm_fenv_aarch64.h new file mode 100644 index 00000000..5cf0e49b --- /dev/null +++ b/openlibm/include/openlibm_fenv_aarch64.h @@ -0,0 +1,247 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include + +#include "cdefs-compat.h" + +#ifndef __fenv_static +#define __fenv_static static +#endif + +/* The high 32 bits contain fpcr, low 32 contain fpsr. */ +typedef uint64_t fenv_t; +typedef uint64_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x00000001 +#define FE_DIVBYZERO 0x00000002 +#define FE_OVERFLOW 0x00000004 +#define FE_UNDERFLOW 0x00000008 +#define FE_INEXACT 0x00000010 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* + * Rounding modes + * + * We can't just use the hardware bit values here, because that would + * make FE_UPWARD and FE_DOWNWARD negative, which is not allowed. + */ +#define FE_TONEAREST 0x0 +#define FE_UPWARD 0x1 +#define FE_DOWNWARD 0x2 +#define FE_TOWARDZERO 0x3 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) +#define _ROUND_SHIFT 22 + +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +/* We need to be able to map status flag positions to mask flag positions */ +#define _FPUSW_SHIFT 8 +#define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) + +#define __mrs_fpcr(__r) __asm __volatile("mrs %0, fpcr" : "=r" (__r)) +#define __msr_fpcr(__r) __asm __volatile("msr fpcr, %0" : : "r" (__r)) + +#define __mrs_fpsr(__r) __asm __volatile("mrs %0, fpsr" : "=r" (__r)) +#define __msr_fpsr(__r) __asm __volatile("msr fpsr, %0" : : "r" (__r)) + + +__fenv_static inline int +feclearexcept(int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + __r &= ~__excepts; + __msr_fpsr(__r); + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + *__flagp = __r & __excepts; + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + __r &= ~__excepts; + __r |= *__flagp & __excepts; + __msr_fpsr(__r); + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + __r |= __excepts; + __msr_fpsr(__r); + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + return (__r & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + fenv_t __r; + + __mrs_fpcr(__r); + return ((__r >> _ROUND_SHIFT) & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + fenv_t __r; + + if (__round & ~_ROUND_MASK) + return (-1); + __mrs_fpcr(__r); + __r &= ~(_ROUND_MASK << _ROUND_SHIFT); + __r |= __round << _ROUND_SHIFT; + __msr_fpcr(__r); + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + uint64_t fpcr; + uint64_t fpsr; + + __mrs_fpcr(fpcr); + __mrs_fpsr(fpsr); + *__envp = fpsr | (fpcr << 32); + + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fenv_t __r; + + __mrs_fpcr(__r); + *__envp = __r << 32; + __r &= ~(_ENABLE_MASK); + __msr_fpcr(__r); + + __mrs_fpsr(__r); + *__envp |= (uint32_t)__r; + __r &= ~(_ENABLE_MASK); + __msr_fpsr(__r); + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + + __msr_fpcr((*__envp) >> 32); + __msr_fpsr((fenv_t)(uint32_t)*__envp); + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __r; + + __mrs_fpsr(__r); + fesetenv(__envp); + feraiseexcept(__r & FE_ALL_EXCEPT); + return (0); +} + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +static inline int +feenableexcept(int __mask) +{ + fenv_t __old_r, __new_r; + + __mrs_fpcr(__old_r); + __new_r = __old_r | ((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); + __msr_fpcr(__new_r); + return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); +} + +static inline int +fedisableexcept(int __mask) +{ + fenv_t __old_r, __new_r; + + __mrs_fpcr(__old_r); + __new_r = __old_r & ~((__mask & FE_ALL_EXCEPT) << _FPUSW_SHIFT); + __msr_fpcr(__new_r); + return ((__old_r >> _FPUSW_SHIFT) & FE_ALL_EXCEPT); +} + +static inline int +fegetexcept(void) +{ + fenv_t __r; + + __mrs_fpcr(__r); + return ((__r & _ENABLE_MASK) >> _FPUSW_SHIFT); +} + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/openlibm/include/openlibm_fenv_amd64.h b/openlibm/include/openlibm_fenv_amd64.h index 9e302bd9..c6db210e 100644 --- a/openlibm/include/openlibm_fenv_amd64.h +++ b/openlibm/include/openlibm_fenv_amd64.h @@ -29,11 +29,10 @@ #ifndef _FENV_H_ #define _FENV_H_ +#include #include "cdefs-compat.h" #include "types-compat.h" -#include "math_private.h" - #ifndef __fenv_static #define __fenv_static static #endif diff --git a/openlibm/include/openlibm_fenv_arm.h b/openlibm/include/openlibm_fenv_arm.h index ff1946ff..8223a01d 100644 --- a/openlibm/include/openlibm_fenv_arm.h +++ b/openlibm/include/openlibm_fenv_arm.h @@ -66,12 +66,9 @@ extern const fenv_t __fe_dfl_env; #define _FPUSW_SHIFT 16 #define _ENABLE_MASK (FE_ALL_EXCEPT << _FPUSW_SHIFT) -#if defined(__aarch64__) -#define __rfs(__fpsr) __asm __volatile("mrs %0,fpsr" : "=r" (*(__fpsr))) -#define __wfs(__fpsr) __asm __volatile("msr fpsr,%0" : : "r" (__fpsr)) /* Test for hardware support for ARM floating point operations, explicitly checking for float and double support, see "ARM C Language Extensions", 6.5.1 */ -#elif defined(__ARM_FP) && (__ARM_FP & 0x0C) != 0 +#if defined(__ARM_FP) && (__ARM_FP & 0x0C) != 0 #define __rfs(__fpsr) __asm __volatile("vmrs %0,fpscr" : "=&r" (*(__fpsr))) #define __wfs(__fpsr) __asm __volatile("vmsr fpscr,%0" : : "r" (__fpsr)) #else diff --git a/openlibm/include/openlibm_fenv_i387.h b/openlibm/include/openlibm_fenv_i387.h index c3a987c5..ec4eb87c 100644 --- a/openlibm/include/openlibm_fenv_i387.h +++ b/openlibm/include/openlibm_fenv_i387.h @@ -29,6 +29,7 @@ #ifndef _FENV_H_ #define _FENV_H_ +#include "openlibm_defs.h" #include "cdefs-compat.h" #include "types-compat.h" @@ -88,8 +89,8 @@ __BEGIN_DECLS /* After testing for SSE support once, we cache the result in __has_sse. */ enum __sse_support { __SSE_YES, __SSE_NO, __SSE_UNK }; -extern enum __sse_support __has_sse; -int __test_sse(void); +OLM_DLLEXPORT extern enum __sse_support __has_sse; +OLM_DLLEXPORT int __test_sse(void); #ifdef __SSE__ #define __HAS_SSE() 1 #else @@ -98,7 +99,7 @@ int __test_sse(void); #endif /* Default floating-point environment */ -extern const fenv_t __fe_dfl_env; +OLM_DLLEXPORT extern const fenv_t __fe_dfl_env; #define FE_DFL_ENV (&__fe_dfl_env) #define __fldcw(__cw) __asm __volatile("fldcw %0" : : "m" (__cw)) @@ -150,8 +151,8 @@ fegetexceptflag(fexcept_t *__flagp, int __excepts) return (0); } -int fesetexceptflag(const fexcept_t *__flagp, int __excepts); -int feraiseexcept(int __excepts); +OLM_DLLEXPORT int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +OLM_DLLEXPORT int feraiseexcept(int __excepts); __fenv_static inline int fetestexcept(int __excepts) @@ -206,8 +207,8 @@ fesetround(int __round) return (0); } -int fegetenv(fenv_t *__envp); -int feholdexcept(fenv_t *__envp); +OLM_DLLEXPORT int fegetenv(fenv_t *__envp); +OLM_DLLEXPORT int feholdexcept(fenv_t *__envp); __fenv_static inline int fesetenv(const fenv_t *__envp) @@ -231,12 +232,12 @@ fesetenv(const fenv_t *__envp) return (0); } -int feupdateenv(const fenv_t *__envp); +OLM_DLLEXPORT int feupdateenv(const fenv_t *__envp); #if __BSD_VISIBLE -int feenableexcept(int __mask); -int fedisableexcept(int __mask); +OLM_DLLEXPORT int feenableexcept(int __mask); +OLM_DLLEXPORT int fedisableexcept(int __mask); /* We currently provide no external definition of fegetexcept(). */ static inline int diff --git a/openlibm/include/openlibm_fenv_loongarch64.h b/openlibm/include/openlibm_fenv_loongarch64.h new file mode 100644 index 00000000..cfaf0207 --- /dev/null +++ b/openlibm/include/openlibm_fenv_loongarch64.h @@ -0,0 +1,226 @@ +/*- + * Copyright (c) 2023 Yifan An + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include +#include "cdefs-compat.h" + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef uint32_t fenv_t; +typedef uint32_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x100000 +#define FE_DIVBYZERO 0x080000 +#define FE_OVERFLOW 0x040000 +#define FE_UNDERFLOW 0x020000 +#define FE_INEXACT 0x010000 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* Rounding modes */ +#define FE_TONEAREST 0x0000 +#define FE_TOWARDZERO 0x0100 +#define FE_DOWNWARD 0x0200 +#define FE_UPWARD 0x0300 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) + +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +#define _FPU_MASK_V 0x10 +#define _FPU_MASK_Z 0x08 +#define _FPU_MASK_O 0x04 +#define _FPU_MASK_U 0x02 +#define _FPU_MASK_I 0x01 + +#define _FPUSW_SHIFT 16 +#define _ENABLE_MASK (_FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U | _FPU_MASK_I) + +#define __rfs(__fpsr) __asm __volatile("movfcsr2gr %0,$r0" : "=r"(__fpsr)) +#define __wfs(__fpsr) __asm __volatile("movgr2fcsr $r0,%0" : : "r"(__fpsr)) + +__fenv_static inline int +feclearexcept(int __excepts) +{ + fexcept_t __fpsr; + + __rfs(__fpsr); + __fpsr &= ~__excepts; + __wfs(__fpsr); + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fpsr; + + __rfs(__fpsr); + *__flagp = __fpsr & __excepts; + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fpsr; + + __rfs(__fpsr); + __fpsr &= ~__excepts; + __fpsr |= *__flagp & __excepts; + __wfs(__fpsr); + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + fexcept_t __ex = __excepts; + + fesetexceptflag(&__ex, __excepts); /* XXX */ + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t __fpsr; + + __rfs(__fpsr); + return (__fpsr & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + fexcept_t __fpsr; + + __rfs(__fpsr); + return __fpsr & _ROUND_MASK; +} + +__fenv_static inline int +fesetround(int __round) +{ + fexcept_t __fpsr; + if ((__round & ~_ROUND_MASK) != 0) + return 1; + + __rfs(__fpsr); + __fpsr &= ~_ROUND_MASK; + __fpsr |= __round; + __wfs(__fpsr); + + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + __rfs(*__envp); + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fenv_t __env; + + __rfs(__env); + *__envp = __env; + __env &= ~(FE_ALL_EXCEPT | _FPU_MASK_V | _FPU_MASK_Z | _FPU_MASK_O | _FPU_MASK_U | _FPU_MASK_I); + __wfs(__env); + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + __wfs(*__envp); + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __fpsr; + + __rfs(__fpsr); + __wfs(*__envp); + feraiseexcept(__fpsr & FE_ALL_EXCEPT); + return (0); +} + +#if __BSD_VISIBLE + +static inline int +feenableexcept(int __mask) +{ + fenv_t __old_fpsr, __new_fpsr; + + __rfs(__new_fpsr); + __old_fpsr = (__new_fpsr & _ENABLE_MASK) << _FPUSW_SHIFT; + __new_fpsr |= (__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT; + __wfs(__new_fpsr); + return __old_fpsr; +} + +static inline int +fedisableexcept(int __mask) +{ + fenv_t __old_fpsr, __new_fpsr; + + __rfs(__new_fpsr); + __old_fpsr = (__new_fpsr & _ENABLE_MASK) << _FPUSW_SHIFT; + __new_fpsr &= ~((__mask & FE_ALL_EXCEPT) >> _FPUSW_SHIFT); + __wfs(__new_fpsr); + return __old_fpsr; +} + +static inline int +fegetexcept(void) +{ + fenv_t __fpsr; + + __rfs(__fpsr); + return ((__fpsr & _ENABLE_MASK) << _FPUSW_SHIFT); +} + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ \ No newline at end of file diff --git a/openlibm/include/openlibm_fenv_mips.h b/openlibm/include/openlibm_fenv_mips.h new file mode 100644 index 00000000..980252f7 --- /dev/null +++ b/openlibm/include/openlibm_fenv_mips.h @@ -0,0 +1,278 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include +#include "cdefs-compat.h" + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef uint32_t fenv_t; +typedef uint32_t fexcept_t; + +/* Exception flags */ +#ifdef __mips_soft_float +#define _FPUSW_SHIFT 16 +#define FE_INVALID 0x0001 +#define FE_DIVBYZERO 0x0002 +#define FE_OVERFLOW 0x0004 +#define FE_UNDERFLOW 0x0008 +#define FE_INEXACT 0x0010 +#else +#define _FCSR_CAUSE_SHIFT 10 +#define FE_INVALID 0x0040 +#define FE_DIVBYZERO 0x0020 +#define FE_OVERFLOW 0x0010 +#define FE_UNDERFLOW 0x0008 +#define FE_INEXACT 0x0004 +#endif +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* Rounding modes */ +#define FE_TONEAREST 0x0000 +#define FE_TOWARDZERO 0x0001 +#define FE_UPWARD 0x0002 +#define FE_DOWNWARD 0x0003 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +/* We need to be able to map status flag positions to mask flag positions */ +#define _ENABLE_SHIFT 5 +#define _ENABLE_MASK (FE_ALL_EXCEPT << _ENABLE_SHIFT) + +#ifndef __mips_soft_float +#define __cfc1(__fcsr) __asm __volatile("cfc1 %0, $31" : "=r" (__fcsr)) +#define __ctc1(__fcsr) __asm __volatile("ctc1 %0, $31" :: "r" (__fcsr)) +#endif + +#ifdef __mips_soft_float +int feclearexcept(int __excepts); +int fegetexceptflag(fexcept_t *__flagp, int __excepts); +int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +int feraiseexcept(int __excepts); +int fetestexcept(int __excepts); +int fegetround(void); +int fesetround(int __round); +int fegetenv(fenv_t *__envp); +int feholdexcept(fenv_t *__envp); +int fesetenv(const fenv_t *__envp); +int feupdateenv(const fenv_t *__envp); +#else +__fenv_static inline int +feclearexcept(int __excepts) +{ + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + fcsr &= ~(__excepts | (__excepts << _FCSR_CAUSE_SHIFT)); + __ctc1(fcsr); + + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + *__flagp = fcsr & __excepts; + + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + fcsr &= ~__excepts; + fcsr |= *__flagp & __excepts; + __ctc1(fcsr); + + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + fcsr |= __excepts | (__excepts << _FCSR_CAUSE_SHIFT); + __ctc1(fcsr); + + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t fcsr; + + __excepts &= FE_ALL_EXCEPT; + __cfc1(fcsr); + + return (fcsr & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + fexcept_t fcsr; + + __cfc1(fcsr); + + return (fcsr & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + fexcept_t fcsr; + + if (__round & ~_ROUND_MASK) + return (-1); + + __cfc1(fcsr); + fcsr &= ~_ROUND_MASK; + fcsr |= __round; + __ctc1(fcsr); + + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + + __cfc1(*__envp); + + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fexcept_t fcsr; + + __cfc1(fcsr); + *__envp = fcsr; + fcsr &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); + __ctc1(fcsr); + + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + + __ctc1(*__envp); + + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t fcsr; + + __cfc1(fcsr); + fesetenv(__envp); + feraiseexcept(fcsr); + + return (0); +} +#endif /* !__mips_soft_float */ + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +#ifdef __mips_soft_float +int feenableexcept(int __mask); +int fedisableexcept(int __mask); +int fegetexcept(void); +#else +static inline int +feenableexcept(int __mask) +{ + fenv_t __old_fcsr, __new_fcsr; + + __cfc1(__old_fcsr); + __new_fcsr = __old_fcsr | (__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT; + __ctc1(__new_fcsr); + + return ((__old_fcsr >> _ENABLE_SHIFT) & FE_ALL_EXCEPT); +} + +static inline int +fedisableexcept(int __mask) +{ + fenv_t __old_fcsr, __new_fcsr; + + __cfc1(__old_fcsr); + __new_fcsr = __old_fcsr & ~((__mask & FE_ALL_EXCEPT) << _ENABLE_SHIFT); + __ctc1(__new_fcsr); + + return ((__old_fcsr >> _ENABLE_SHIFT) & FE_ALL_EXCEPT); +} + +static inline int +fegetexcept(void) +{ + fexcept_t fcsr; + + __cfc1(fcsr); + + return ((fcsr & _ENABLE_MASK) >> _ENABLE_SHIFT); +} + +#endif /* !__mips_soft_float */ + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/openlibm/include/openlibm_fenv_powerpc.h b/openlibm/include/openlibm_fenv_powerpc.h index 2b05bd48..232ea833 100644 --- a/openlibm/include/openlibm_fenv_powerpc.h +++ b/openlibm/include/openlibm_fenv_powerpc.h @@ -97,7 +97,7 @@ extern const fenv_t __fe_dfl_env; union __fpscr { double __d; struct { -#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) fenv_t __reg; __uint32_t __junk; #else diff --git a/openlibm/include/openlibm_fenv_riscv.h b/openlibm/include/openlibm_fenv_riscv.h new file mode 100644 index 00000000..e8ce78e7 --- /dev/null +++ b/openlibm/include/openlibm_fenv_riscv.h @@ -0,0 +1,261 @@ +/*- + * Copyright (c) 2004-2005 David Schultz + * Copyright (c) 2015-2016 Ruslan Bukin + * All rights reserved. + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/lib/msun/riscv/fenv.h 332792 2018-04-19 20:36:15Z brooks $ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include +#include "cdefs-compat.h" + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef uint64_t fenv_t; +typedef uint64_t fexcept_t; + +/* Exception flags */ +#define FE_INVALID 0x0010 +#define FE_DIVBYZERO 0x0008 +#define FE_OVERFLOW 0x0004 +#define FE_UNDERFLOW 0x0002 +#define FE_INEXACT 0x0001 +#define FE_ALL_EXCEPT (FE_DIVBYZERO | FE_INEXACT | \ + FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW) + +/* + * RISC-V Rounding modes + */ +#define _ROUND_SHIFT 5 +#define FE_TONEAREST (0x00 << _ROUND_SHIFT) +#define FE_TOWARDZERO (0x01 << _ROUND_SHIFT) +#define FE_DOWNWARD (0x02 << _ROUND_SHIFT) +#define FE_UPWARD (0x03 << _ROUND_SHIFT) +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) + +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +#if !defined(__riscv_float_abi_soft) && !defined(__riscv_float_abi_double) +#if defined(__riscv_float_abi_single) +#error single precision floating point ABI not supported +#else +#error compiler did not set soft/hard float macros +#endif +#endif + +#ifndef __riscv_float_abi_soft +#define __rfs(__fcsr) __asm __volatile("csrr %0, fcsr" : "=r" (__fcsr)) +#define __wfs(__fcsr) __asm __volatile("csrw fcsr, %0" :: "r" (__fcsr)) +#endif + +#ifdef __riscv_float_abi_soft +int feclearexcept(int __excepts); +int fegetexceptflag(fexcept_t *__flagp, int __excepts); +int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +int feraiseexcept(int __excepts); +int fetestexcept(int __excepts); +int fegetround(void); +int fesetround(int __round); +int fegetenv(fenv_t *__envp); +int feholdexcept(fenv_t *__envp); +int fesetenv(const fenv_t *__envp); +int feupdateenv(const fenv_t *__envp); +#else +__fenv_static inline int +feclearexcept(int __excepts) +{ + + __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); + + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fcsr; + + __rfs(__fcsr); + *__flagp = __fcsr & __excepts; + + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __fcsr; + + __fcsr = *__flagp; + __asm __volatile("csrc fflags, %0" :: "r"(__excepts)); + __asm __volatile("csrs fflags, %0" :: "r"(__fcsr & __excepts)); + + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + + __asm __volatile("csrs fflags, %0" :: "r"(__excepts)); + + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t __fcsr; + + __rfs(__fcsr); + + return (__fcsr & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + fexcept_t __fcsr; + + __rfs(__fcsr); + + return (__fcsr & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + fexcept_t __fcsr; + + if (__round & ~_ROUND_MASK) + return (-1); + + __rfs(__fcsr); + __fcsr &= ~_ROUND_MASK; + __fcsr |= __round; + __wfs(__fcsr); + + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + + __rfs(*__envp); + + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + + /* No exception traps. */ + + return (-1); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + + __wfs(*__envp); + + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __fcsr; + + __rfs(__fcsr); + __wfs(*__envp); + feraiseexcept(__fcsr & FE_ALL_EXCEPT); + + return (0); +} +#endif /* !__riscv_float_abi_soft */ + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +#ifdef __riscv_float_abi_soft +int feenableexcept(int __mask); +int fedisableexcept(int __mask); +int fegetexcept(void); +#else +static inline int +feenableexcept(int __mask) +{ + + /* No exception traps. */ + + return (-1); +} + +static inline int +fedisableexcept(int __mask) +{ + + /* No exception traps. */ + + return (0); +} + +static inline int +fegetexcept(void) +{ + + /* No exception traps. */ + + return (0); +} +#endif /* !__riscv_float_abi_soft */ + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/openlibm/include/openlibm_fenv_s390.h b/openlibm/include/openlibm_fenv_s390.h new file mode 100644 index 00000000..84ef080d --- /dev/null +++ b/openlibm/include/openlibm_fenv_s390.h @@ -0,0 +1,235 @@ +/*- + * Copyright (c) 2016 Dan Horák + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _FENV_H_ +#define _FENV_H_ + +#include + +#ifndef __fenv_static +#define __fenv_static static +#endif + +typedef __uint32_t fenv_t; +typedef __uint32_t fexcept_t; + +/* Exception flags */ +#define FE_INEXACT 0x080000 +#define FE_UNDERFLOW 0x100000 +#define FE_OVERFLOW 0x200000 +#define FE_DIVBYZERO 0x400000 +#define FE_INVALID 0x800000 /* all types of invalid FP ops */ + +#define FE_ALL_EXCEPT (FE_INVALID | FE_DIVBYZERO | FE_INEXACT | FE_OVERFLOW | FE_UNDERFLOW) + +/* Rounding modes */ +#define FE_TONEAREST 0x0000 +#define FE_TOWARDZERO 0x0001 +#define FE_UPWARD 0x0002 +#define FE_DOWNWARD 0x0003 +#define _ROUND_MASK (FE_TONEAREST | FE_DOWNWARD | \ + FE_UPWARD | FE_TOWARDZERO) + +__BEGIN_DECLS + +/* Default floating-point environment */ +extern const fenv_t __fe_dfl_env; +#define FE_DFL_ENV (&__fe_dfl_env) + +/* We need to be able to map status flag positions to mask flag positions */ +#define _FPC_EXC_MASK_SHIFT 8 +#define _ENABLE_MASK ((FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \ + FE_OVERFLOW | FE_UNDERFLOW) << _FPC_EXC_MASK_SHIFT) + +/* Macros for accessing the hardware control word. */ +#define _FPU_GETCW(cw) __asm__ __volatile__ ("efpc %0,0" : "=d" (cw)) +#define _FPU_SETCW(cw) __asm__ __volatile__ ("sfpc %0,0" : : "d" (cw)) + +__fenv_static inline int +feclearexcept(int __excepts) +{ + fexcept_t __r; + + if (__excepts & FE_INVALID) + __excepts |= FE_ALL_EXCEPT; + _FPU_GETCW(__r); + __r &= ~__excepts; + _FPU_SETCW(__r); + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + *__flagp = __r & __excepts; + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + fexcept_t __r; + + if (__excepts & FE_INVALID) + __excepts |= FE_ALL_EXCEPT; + _FPU_GETCW(__r); + __r &= ~__excepts; + __r |= *__flagp & __excepts; + _FPU_SETCW(__r); + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + __r |= __excepts; + _FPU_SETCW(__r); + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + return (__r & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + return (__r & _ROUND_MASK); +} + +__fenv_static inline int +fesetround(int __round) +{ + fexcept_t __r; + + if (__round & ~_ROUND_MASK) + return (-1); + + _FPU_GETCW(__r); + __r &= ~_ROUND_MASK; + __r |= __round; + _FPU_SETCW(__r); + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + _FPU_GETCW(*__envp); + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + *__envp = __r; + __r &= ~(FE_ALL_EXCEPT | _ENABLE_MASK); + _FPU_SETCW(__r); + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + _FPU_SETCW(*__envp); + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + __r &= FE_ALL_EXCEPT; + __r |= *__envp; + _FPU_SETCW(__r); + return (0); +} + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +static inline int +feenableexcept(int __mask) +{ + fenv_t __r; + fenv_t __oldmask; + + _FPU_GETCW(__r); + __oldmask = __r; + __r |= (__mask & FE_ALL_EXCEPT) << _FPC_EXC_MASK_SHIFT; + _FPU_SETCW(__r); + return ((__oldmask & _ENABLE_MASK) >> _FPC_EXC_MASK_SHIFT); +} + +static inline int +fedisableexcept(int __mask) +{ + fenv_t __r; + fenv_t __oldmask; + + _FPU_GETCW(__r); + __oldmask = __r; + __r &= ~((__mask & FE_ALL_EXCEPT) << _FPC_EXC_MASK_SHIFT); + _FPU_SETCW(__r); + return ((__oldmask & _ENABLE_MASK) >> _FPC_EXC_MASK_SHIFT); +} + +static inline int +fegetexcept(void) +{ + fexcept_t __r; + + _FPU_GETCW(__r); + return (__r & (_ENABLE_MASK >> _FPC_EXC_MASK_SHIFT)); +} + +#endif /* __BSD_VISIBLE */ + +__END_DECLS + +#endif /* !_FENV_H_ */ diff --git a/openlibm/include/openlibm_math.h b/openlibm/include/openlibm_math.h index e17e6ad9..701ad705 100644 --- a/openlibm/include/openlibm_math.h +++ b/openlibm/include/openlibm_math.h @@ -18,6 +18,8 @@ #include #else /* !OPENLIBM_USE_HOST_MATH_H */ +#include + #ifndef OPENLIBM_MATH_H #define OPENLIBM_MATH_H @@ -25,24 +27,14 @@ #define __WIN32__ #endif -#ifndef __arm__ -#define LONG_DOUBLE +#if !defined(__arm__) && !defined(__wasm__) +#define OLM_LONG_DOUBLE #endif #ifndef __pure2 #define __pure2 #endif -#ifdef _WIN32 -# ifdef IMPORT_EXPORTS -# define OLM_DLLEXPORT __declspec(dllimport) -# else -# define OLM_DLLEXPORT __declspec(dllexport) -# endif -#else -#define OLM_DLLEXPORT __attribute__ ((visibility("default"))) -#endif - /* * ANSI/POSIX */ @@ -182,7 +174,7 @@ extern const union __nan_un { #define MAXFLOAT ((float)3.40282346638528860e+38) #ifndef OPENLIBM_ONLY_THREAD_SAFE -extern int signgam; +OLM_DLLEXPORT extern int signgam; #endif #endif /* __BSD_VISIBLE || __XSI_VISIBLE */ @@ -312,6 +304,7 @@ OLM_DLLEXPORT double trunc(double); * BSD math library entry points */ #if __BSD_VISIBLE +OLM_DLLEXPORT int isinff(float) __pure2; OLM_DLLEXPORT int isnanf(float) __pure2; /* diff --git a/openlibm/loongarch64/Make.files b/openlibm/loongarch64/Make.files new file mode 100644 index 00000000..483a7ccc --- /dev/null +++ b/openlibm/loongarch64/Make.files @@ -0,0 +1 @@ +$(CUR_SRCS) = fenv.c diff --git a/openlibm/loongarch64/fenv.c b/openlibm/loongarch64/fenv.c new file mode 100644 index 00000000..9c95f2aa --- /dev/null +++ b/openlibm/loongarch64/fenv.c @@ -0,0 +1,27 @@ +#define __fenv_static +#include + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +/* + * Hopefully the system ID byte is immutable, so it's valid to use + * this as a default environment. + */ +const fenv_t __fe_dfl_env = 0; + +extern inline int feclearexcept(int __excepts); +extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); +extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +extern inline int feraiseexcept(int __excepts); +extern inline int fetestexcept(int __excepts); +extern inline int fegetround(void); +extern inline int fesetround(int __round); +extern inline int fegetenv(fenv_t *__envp); +extern inline int feholdexcept(fenv_t *__envp); +extern inline int fesetenv(const fenv_t *__envp); +extern inline int feupdateenv(const fenv_t *__envp); +extern inline int feenableexcept(int __mask); +extern inline int fedisableexcept(int __mask); +extern inline int fegetexcept(void); \ No newline at end of file diff --git a/openlibm/mips/Make.files b/openlibm/mips/Make.files new file mode 100644 index 00000000..483a7ccc --- /dev/null +++ b/openlibm/mips/Make.files @@ -0,0 +1 @@ +$(CUR_SRCS) = fenv.c diff --git a/openlibm/mips/fenv-softfloat.h b/openlibm/mips/fenv-softfloat.h new file mode 100644 index 00000000..05113359 --- /dev/null +++ b/openlibm/mips/fenv-softfloat.h @@ -0,0 +1,184 @@ +/*- + * Copyright (c) 2004-2011 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _FENV_H_ +#error "This file is meant to be included only by ." +#endif + +/* + * This file implements the functionality of on platforms that + * lack an FPU and use softfloat in libc for floating point. To use it, + * you must write an that provides the following: + * + * - a typedef for fenv_t, which may be an integer or struct type + * - a typedef for fexcept_t (XXX This file assumes fexcept_t is a + * simple integer type containing the exception mask.) + * - definitions of FE_* constants for the five exceptions and four + * rounding modes in IEEE 754, as described in fenv(3) + * - a definition, and the corresponding external symbol, for FE_DFL_ENV + * - a macro __set_env(env, flags, mask, rnd), which sets the given fenv_t + * from the exception flags, mask, and rounding mode + * - macros __env_flags(env), __env_mask(env), and __env_round(env), which + * extract fields from an fenv_t + * - a definition of __fenv_static + * + * If the architecture supports an optional FPU, it's recommended that you + * define fenv_t and fexcept_t to match the hardware ABI. Otherwise, it + * doesn't matter how you define them. + */ + +extern int __softfloat_float_exception_flags; +extern int __softfloat_float_exception_mask; +extern int __softfloat_float_rounding_mode; +void __softfloat_float_raise(int); + +__fenv_static inline int +feclearexcept(int __excepts) +{ + + __softfloat_float_exception_flags &= ~__excepts; + return (0); +} + +__fenv_static inline int +fegetexceptflag(fexcept_t *__flagp, int __excepts) +{ + + *__flagp = __softfloat_float_exception_flags & __excepts; + return (0); +} + +__fenv_static inline int +fesetexceptflag(const fexcept_t *__flagp, int __excepts) +{ + + __softfloat_float_exception_flags &= ~__excepts; + __softfloat_float_exception_flags |= *__flagp & __excepts; + return (0); +} + +__fenv_static inline int +feraiseexcept(int __excepts) +{ + + __softfloat_float_raise(__excepts); + return (0); +} + +__fenv_static inline int +fetestexcept(int __excepts) +{ + + return (__softfloat_float_exception_flags & __excepts); +} + +__fenv_static inline int +fegetround(void) +{ + + return (__softfloat_float_rounding_mode); +} + +__fenv_static inline int +fesetround(int __round) +{ + + __softfloat_float_rounding_mode = __round; + return (0); +} + +__fenv_static inline int +fegetenv(fenv_t *__envp) +{ + + __set_env(*__envp, __softfloat_float_exception_flags, + __softfloat_float_exception_mask, __softfloat_float_rounding_mode); + return (0); +} + +__fenv_static inline int +feholdexcept(fenv_t *__envp) +{ + fenv_t __env; + + fegetenv(__envp); + __softfloat_float_exception_flags = 0; + __softfloat_float_exception_mask = 0; + return (0); +} + +__fenv_static inline int +fesetenv(const fenv_t *__envp) +{ + + __softfloat_float_exception_flags = __env_flags(*__envp); + __softfloat_float_exception_mask = __env_mask(*__envp); + __softfloat_float_rounding_mode = __env_round(*__envp); + return (0); +} + +__fenv_static inline int +feupdateenv(const fenv_t *__envp) +{ + int __oflags = __softfloat_float_exception_flags; + + fesetenv(__envp); + feraiseexcept(__oflags); + return (0); +} + +#if __BSD_VISIBLE + +/* We currently provide no external definitions of the functions below. */ + +__fenv_static inline int +feenableexcept(int __mask) +{ + int __omask = __softfloat_float_exception_mask; + + __softfloat_float_exception_mask |= __mask; + return (__omask); +} + +__fenv_static inline int +fedisableexcept(int __mask) +{ + int __omask = __softfloat_float_exception_mask; + + __softfloat_float_exception_mask &= ~__mask; + return (__omask); +} + +__fenv_static inline int +fegetexcept(void) +{ + + return (__softfloat_float_exception_mask); +} + +#endif /* __BSD_VISIBLE */ \ No newline at end of file diff --git a/openlibm/mips/fenv.c b/openlibm/mips/fenv.c new file mode 100644 index 00000000..4a7ed80c --- /dev/null +++ b/openlibm/mips/fenv.c @@ -0,0 +1,67 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#define __fenv_static +#include "openlibm_fenv.h" + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +/* + * Hopefully the system ID byte is immutable, so it's valid to use + * this as a default environment. + */ +const fenv_t __fe_dfl_env = 0; + +#ifdef __mips_soft_float +#define __set_env(env, flags, mask, rnd) env = ((flags) \ + | (mask)<<_FPUSW_SHIFT \ + | (rnd) << 24) +#define __env_flags(env) ((env) & FE_ALL_EXCEPT) +#define __env_mask(env) (((env) >> _FPUSW_SHIFT) \ + & FE_ALL_EXCEPT) +#define __env_round(env) (((env) >> 24) & _ROUND_MASK) +#include "fenv-softfloat.h" +#endif + +extern inline int feclearexcept(int __excepts); +extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); +extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +extern inline int feraiseexcept(int __excepts); +extern inline int fetestexcept(int __excepts); +extern inline int fegetround(void); +extern inline int fesetround(int __round); +extern inline int fegetenv(fenv_t *__envp); +extern inline int feholdexcept(fenv_t *__envp); +extern inline int fesetenv(const fenv_t *__envp); +extern inline int feupdateenv(const fenv_t *__envp); +extern inline int feenableexcept(int __mask); +extern inline int fedisableexcept(int __mask); +extern inline int fegetexcept(void); + diff --git a/openlibm/openlibm.pc.in b/openlibm/openlibm.pc.in index 242d4479..bfad8762 100644 --- a/openlibm/openlibm.pc.in +++ b/openlibm/openlibm.pc.in @@ -1,10 +1,6 @@ -exec_prefix=${prefix} -includedir=${prefix}/include -libdir=${exec_prefix}/lib - Name: openlibm Version: ${version} -URL: https://github.com/JuliaLang/openlibm +URL: https://github.com/JuliaMath/openlibm Description: High quality system independent, open source libm. Cflags: -I${includedir} Libs: -L${libdir} -lopenlibm diff --git a/openlibm/powerpc/fenv.c b/openlibm/powerpc/fenv.c index 78e6015e..bf7d0cbe 100644 --- a/openlibm/powerpc/fenv.c +++ b/openlibm/powerpc/fenv.c @@ -26,7 +26,6 @@ * $FreeBSD$ */ -#define __fenv_static #include #ifdef __GNUC_GNU_INLINE__ diff --git a/openlibm/riscv64/Make.files b/openlibm/riscv64/Make.files new file mode 100644 index 00000000..483a7ccc --- /dev/null +++ b/openlibm/riscv64/Make.files @@ -0,0 +1 @@ +$(CUR_SRCS) = fenv.c diff --git a/openlibm/riscv64/fenv.c b/openlibm/riscv64/fenv.c new file mode 100644 index 00000000..467bffe8 --- /dev/null +++ b/openlibm/riscv64/fenv.c @@ -0,0 +1,63 @@ +/*- + * Copyright (c) 2004 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/lib/msun/riscv/fenv.c 332792 2018-04-19 20:36:15Z brooks $ + */ + +#define __fenv_static +#include + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +/* + * Hopefully the system ID byte is immutable, so it's valid to use + * this as a default environment. + */ +const fenv_t __fe_dfl_env = 0; + +#ifdef __riscv_float_abi_soft +#define __set_env(env, flags, mask, rnd) env = ((flags) | (rnd) << 5) +#define __env_flags(env) ((env) & FE_ALL_EXCEPT) +#define __env_mask(env) (0) /* No exception traps. */ +#define __env_round(env) (((env) >> 5) & _ROUND_MASK) +#include "fenv-softfloat.h" +#endif + +extern inline int feclearexcept(int __excepts); +extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); +extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +extern inline int feraiseexcept(int __excepts); +extern inline int fetestexcept(int __excepts); +extern inline int fegetround(void); +extern inline int fesetround(int __round); +extern inline int fegetenv(fenv_t *__envp); +extern inline int feholdexcept(fenv_t *__envp); +extern inline int fesetenv(const fenv_t *__envp); +extern inline int feupdateenv(const fenv_t *__envp); +extern inline int feenableexcept(int __mask); +extern inline int fedisableexcept(int __mask); +extern inline int fegetexcept(void); diff --git a/openlibm/s390/Make.files b/openlibm/s390/Make.files new file mode 100644 index 00000000..483a7ccc --- /dev/null +++ b/openlibm/s390/Make.files @@ -0,0 +1 @@ +$(CUR_SRCS) = fenv.c diff --git a/openlibm/s390/fenv.c b/openlibm/s390/fenv.c new file mode 100644 index 00000000..2bcce760 --- /dev/null +++ b/openlibm/s390/fenv.c @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2016 Dan Horák + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + * cloned from ppc/fenv.c + */ + +#define __fenv_static +#include + +#ifdef __GNUC_GNU_INLINE__ +#error "This file must be compiled with C99 'inline' semantics" +#endif + +const fenv_t __fe_dfl_env = 0x00000000; + +extern inline int feclearexcept(int __excepts); +extern inline int fegetexceptflag(fexcept_t *__flagp, int __excepts); +extern inline int fesetexceptflag(const fexcept_t *__flagp, int __excepts); +extern inline int feraiseexcept(int __excepts); +extern inline int fetestexcept(int __excepts); +extern inline int fegetround(void); +extern inline int fesetround(int __round); +extern inline int fegetenv(fenv_t *__envp); +extern inline int feholdexcept(fenv_t *__envp); +extern inline int fesetenv(const fenv_t *__envp); +extern inline int feupdateenv(const fenv_t *__envp); diff --git a/openlibm/src/Make.files b/openlibm/src/Make.files index 5462ffc5..5170403c 100644 --- a/openlibm/src/Make.files +++ b/openlibm/src/Make.files @@ -15,15 +15,14 @@ $(CUR_SRCS) = common.c \ s_copysign.c s_copysignf.c s_cos.c s_cosf.c \ s_csqrt.c s_csqrtf.c s_erf.c s_erff.c \ s_exp2.c s_exp2f.c s_expm1.c s_expm1f.c s_fabs.c s_fabsf.c s_fdim.c \ - s_floor.c s_floorf.c s_fma.c s_fmaf.c \ + s_floor.c s_floorf.c \ s_fmax.c s_fmaxf.c s_fmin.c \ s_fminf.c s_fpclassify.c \ s_frexp.c s_frexpf.c s_ilogb.c s_ilogbf.c \ s_isinf.c s_isfinite.c s_isnormal.c s_isnan.c \ - s_llrint.c s_llrintf.c s_llround.c s_llroundf.c \ - s_log1p.c s_log1pf.c s_logb.c s_logbf.c s_lrint.c s_lrintf.c \ - s_lround.c s_lroundf.c s_modf.c s_modff.c \ - s_nearbyint.c s_nextafter.c s_nextafterf.c \ + s_log1p.c s_log1pf.c s_logb.c s_logbf.c \ + s_modf.c s_modff.c \ + s_nextafter.c s_nextafterf.c \ s_nexttowardf.c s_remquo.c s_remquof.c \ s_rint.c s_rintf.c s_round.c s_roundf.c \ s_scalbln.c s_scalbn.c s_scalbnf.c s_signbit.c \ @@ -32,12 +31,20 @@ $(CUR_SRCS) = common.c \ s_trunc.c s_truncf.c s_cpow.c s_cpowf.c \ w_cabs.c w_cabsf.c +ifneq ($(ARCH), wasm32) + +$(CUR_SRCS) += \ + s_fma.c s_fmaf.c s_lrint.c s_lrintf.c s_lround.c s_lroundf.c \ + s_llrint.c s_llrintf.c s_llround.c s_llroundf.c s_nearbyint.c + ifneq ($(OS), WINNT) $(CUR_SRCS) += s_nan.c endif +endif + # Add in long double functions for x86, x64 and aarch64 -ifneq ($(filter $(ARCH),i387 amd64 aarch64),) +ifeq ($(LONG_DOUBLE_NOT_DOUBLE),1) # C99 long double functions $(CUR_SRCS) += s_copysignl.c s_fabsl.c s_llrintl.c s_lrintl.c s_modfl.c diff --git a/openlibm/src/aarch64_fpmath.h b/openlibm/src/aarch64_fpmath.h index c4e407cd..e1fdc63e 100644 --- a/openlibm/src/aarch64_fpmath.h +++ b/openlibm/src/aarch64_fpmath.h @@ -27,18 +27,20 @@ * $FreeBSD: head/lib/libc/aarch64/_fpmath.h 281197 2015-04-07 09:52:14Z andrew $ */ +#include + union IEEEl2bits { long double e; struct { - unsigned long manl :64; - unsigned long manh :48; + uint64_t manl :64; + uint64_t manh :48; unsigned int exp :15; unsigned int sign :1; } bits; /* TODO andrew: Check the packing here */ struct { - unsigned long manl :64; - unsigned long manh :48; + uint64_t manl :64; + uint64_t manh :48; unsigned int expsign :16; } xbits; }; diff --git a/openlibm/src/cdefs-compat.h b/openlibm/src/cdefs-compat.h index fb319656..834c5478 100644 --- a/openlibm/src/cdefs-compat.h +++ b/openlibm/src/cdefs-compat.h @@ -12,64 +12,87 @@ #endif /* !defined(__BEGIN_DECLS) */ #ifdef __GNUC__ -#ifndef __strong_reference +#if defined(__strong_alias) && defined(__NetBSD__) +#define openlibm_strong_reference(sym,alias) __strong_alias(alias,sym) +#elif defined(__strong_reference) +#define openlibm_strong_reference(sym,alias) __strong_reference(sym,alias) +#else #ifdef __APPLE__ -#define __strong_reference(sym,aliassym) __weak_reference(sym,aliassym) +#define openlibm_strong_reference(sym,aliassym) openlibm_weak_reference(sym,aliassym) #else -#define __strong_reference(sym,aliassym) \ - OLM_DLLEXPORT extern __typeof (sym) aliassym __attribute__ ((__alias__ (#sym))); +#define openlibm_strong_reference(sym,aliassym) \ + OLM_DLLEXPORT extern __typeof (aliassym) aliassym __attribute__ ((__alias__ (#sym))); #endif /* __APPLE__ */ #endif /* __strong_reference */ -#ifndef __weak_reference +#ifdef __wasm__ +#define openlibm_weak_reference(sym,alias) openlibm_strong_reference(sym,alias) +#elif defined(__weak_alias) && defined(__NetBSD__) +#define openlibm_weak_reference(sym,alias) __weak_alias(alias,sym) +#elif defined(__weak_reference) +#define openlibm_weak_reference(sym,alias) __weak_reference(sym,alias) +#else #ifdef __ELF__ #ifdef __STDC__ -#define __weak_reference(sym,alias) \ +#define openlibm_weak_reference(sym,alias) \ __asm__(".weak " #alias); \ __asm__(".equ " #alias ", " #sym) -#ifndef __warn_references -#define __warn_references(sym,msg) \ +#ifdef __warn_references +#define openlibm_warn_references(sym,msg) __warn_references(sym,msg) +#else +#define openlibm_warn_references(sym,msg) \ __asm__(".section .gnu.warning." #sym); \ __asm__(".asciz \"" msg "\""); \ __asm__(".previous") #endif /* __warn_references */ #else -#define __weak_reference(sym,alias) \ +#define openlibm_weak_reference(sym,alias) \ __asm__(".weak alias"); \ __asm__(".equ alias, sym") -#ifndef __warn_references -#define __warn_references(sym,msg) \ +#ifdef __warn_references +#define openlibm_warn_references(sym,msg) __warn_references(sym,msg) +#else +#define openlibm_warn_references(sym,msg) \ __asm__(".section .gnu.warning.sym"); \ __asm__(".asciz \"msg\""); \ __asm__(".previous") #endif /* __warn_references */ #endif /* __STDC__ */ #elif defined(__clang__) /* CLANG */ +#if defined(_WIN32) && defined(_X86_) +#define openlibm_asm_symbol_prefix "_" +#else +#define openlibm_asm_symbol_prefix "" +#endif #ifdef __STDC__ -#define __weak_reference(sym,alias) \ - __asm__(".weak_reference " #alias); \ - __asm__(".set " #alias ", " #sym) +#define openlibm_weak_reference(sym,alias) \ + __asm__(".weak_reference " openlibm_asm_symbol_prefix #alias); \ + __asm__(".set " openlibm_asm_symbol_prefix #alias ", " openlibm_asm_symbol_prefix #sym) #else -#define __weak_reference(sym,alias) \ - __asm__(".weak_reference alias");\ - __asm__(".set alias, sym") +#define openlibm_weak_reference(sym,alias) \ + __asm__(".weak_reference openlibm_asm_symbol_prefix/**/alias");\ + __asm__(".set openlibm_asm_symbol_prefix/**/alias, openlibm_asm_symbol_prefix/**/sym") #endif #else /* !__ELF__ */ #ifdef __STDC__ -#define __weak_reference(sym,alias) \ +#define openlibm_weak_reference(sym,alias) \ __asm__(".stabs \"_" #alias "\",11,0,0,0"); \ __asm__(".stabs \"_" #sym "\",1,0,0,0") -#ifndef __warn_references -#define __warn_references(sym,msg) \ +#ifdef __warn_references +#define openlibm_warn_references(sym,msg) __warn_references(sym,msg) +#else +#define openlibm_warn_references(sym,msg) \ __asm__(".stabs \"" msg "\",30,0,0,0"); \ __asm__(".stabs \"_" #sym "\",1,0,0,0") #endif /* __warn_references */ #else -#define __weak_reference(sym,alias) \ +#define openlibm_weak_reference(sym,alias) \ __asm__(".stabs \"_/**/alias\",11,0,0,0"); \ __asm__(".stabs \"_/**/sym\",1,0,0,0") -#ifndef __warn_references -#define __warn_references(sym,msg) \ +#ifdef __warn_references +#define openlibm_warn_references(sym,msg) __warn_references(sym,msg) +#else +#define openlibm_warn_references(sym,msg) \ __asm__(".stabs msg,30,0,0,0"); \ __asm__(".stabs \"_/**/sym\",1,0,0,0") #endif /* __warn_references */ diff --git a/openlibm/src/e_acos.c b/openlibm/src/e_acos.c index b7a74b90..7295ad64 100644 --- a/openlibm/src/e_acos.c +++ b/openlibm/src/e_acos.c @@ -107,5 +107,5 @@ __ieee754_acos(double x) } #if LDBL_MANT_DIG == 53 -__weak_reference(acos, acosl); +openlibm_weak_reference(acos, acosl); #endif diff --git a/openlibm/src/e_acosh.c b/openlibm/src/e_acosh.c index 3f80d95d..1e783a68 100644 --- a/openlibm/src/e_acosh.c +++ b/openlibm/src/e_acosh.c @@ -29,6 +29,7 @@ * acosh(NaN) is NaN without signal. */ +#include #include #include "math_private.h" @@ -61,3 +62,7 @@ __ieee754_acosh(double x) return log1p(t+sqrt(2.0*t+t*t)); } } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(acosh, acoshl); +#endif diff --git a/openlibm/src/e_asin.c b/openlibm/src/e_asin.c index 2ec17645..e287bf1c 100644 --- a/openlibm/src/e_asin.c +++ b/openlibm/src/e_asin.c @@ -113,5 +113,5 @@ __ieee754_asin(double x) } #if LDBL_MANT_DIG == 53 -__weak_reference(asin, asinl); +openlibm_weak_reference(asin, asinl); #endif diff --git a/openlibm/src/e_atan2.c b/openlibm/src/e_atan2.c index c27b41d5..9b021b92 100644 --- a/openlibm/src/e_atan2.c +++ b/openlibm/src/e_atan2.c @@ -71,7 +71,7 @@ __ieee754_atan2(double y, double x) if(((ix|((lx|-lx)>>31))>0x7ff00000)|| ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */ return x+y; - if(((hx-0x3ff00000)|lx)==0) return atan(y); /* x=1.0 */ + if(hx==0x3ff00000&&lx==0) return atan(y); /* x=1.0 */ m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ /* when y = 0 */ @@ -125,5 +125,5 @@ __ieee754_atan2(double y, double x) } #if LDBL_MANT_DIG == 53 -__weak_reference(atan2, atan2l); +openlibm_weak_reference(atan2, atan2l); #endif diff --git a/openlibm/src/e_atanh.c b/openlibm/src/e_atanh.c index b278af37..5e1db914 100644 --- a/openlibm/src/e_atanh.c +++ b/openlibm/src/e_atanh.c @@ -33,6 +33,7 @@ * */ +#include #include #include "math_private.h" @@ -61,3 +62,7 @@ __ieee754_atanh(double x) t = 0.5*log1p((x+x)/(one-x)); if(hx>=0) return t; else return -t; } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(atanh, atanhl); +#endif diff --git a/openlibm/src/e_cosh.c b/openlibm/src/e_cosh.c index a4bfe0b5..2e765706 100644 --- a/openlibm/src/e_cosh.c +++ b/openlibm/src/e_cosh.c @@ -35,6 +35,7 @@ * only cosh(0)=1 is exact for finite x. */ +#include #include #include "math_private.h" @@ -78,3 +79,7 @@ __ieee754_cosh(double x) /* |x| > overflowthresold, cosh(x) overflow */ return huge*huge; } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(cosh, coshl); +#endif diff --git a/openlibm/src/e_exp.c b/openlibm/src/e_exp.c index ed0e3fee..639b9fe1 100644 --- a/openlibm/src/e_exp.c +++ b/openlibm/src/e_exp.c @@ -165,3 +165,7 @@ __ieee754_exp(double x) /* default IEEE double exp */ return y*twopk*twom1000; } } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(exp, expl); +#endif diff --git a/openlibm/src/e_hypot.c b/openlibm/src/e_hypot.c index 23fdc954..3f4c1d14 100644 --- a/openlibm/src/e_hypot.c +++ b/openlibm/src/e_hypot.c @@ -127,5 +127,5 @@ __ieee754_hypot(double x, double y) } #if LDBL_MANT_DIG == 53 -__weak_reference(hypot, hypotl); +openlibm_weak_reference(hypot, hypotl); #endif diff --git a/openlibm/src/e_hypotl.c b/openlibm/src/e_hypotl.c index 047484d6..26327745 100644 --- a/openlibm/src/e_hypotl.c +++ b/openlibm/src/e_hypotl.c @@ -82,7 +82,7 @@ hypotl(long double x, long double y) man_t manh, manl; GET_LDBL_MAN(manh,manl,b); if((manh|manl)==0) return a; - t1=0; + t1=1; SET_HIGH_WORD(t1,ESW(MAX_EXP-2)); /* t1=2^(MAX_EXP-2) */ b *= t1; a *= t1; diff --git a/openlibm/src/e_log.c b/openlibm/src/e_log.c index 4e0a0a9c..29584bb9 100644 --- a/openlibm/src/e_log.c +++ b/openlibm/src/e_log.c @@ -65,6 +65,7 @@ * to produce the hexadecimal values shown. */ +#include #include #include "math_private.h" @@ -139,3 +140,7 @@ __ieee754_log(double x) return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f); } } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(log, logl); +#endif diff --git a/openlibm/src/e_log10.c b/openlibm/src/e_log10.c index 5d20746f..8e3c4e08 100644 --- a/openlibm/src/e_log10.c +++ b/openlibm/src/e_log10.c @@ -22,6 +22,7 @@ * in not-quite-routine extra precision. */ +#include #include #include "math_private.h" @@ -86,3 +87,7 @@ __ieee754_log10(double x) return val_lo + val_hi; } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(log10, log10l); +#endif diff --git a/openlibm/src/e_log2.c b/openlibm/src/e_log2.c index 9fb21a19..15702332 100644 --- a/openlibm/src/e_log2.c +++ b/openlibm/src/e_log2.c @@ -24,6 +24,7 @@ * in not-quite-routine extra precision. */ +#include #include #include "math_private.h" @@ -109,3 +110,7 @@ __ieee754_log2(double x) return val_lo + val_hi; } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(log2, log2l); +#endif diff --git a/openlibm/src/e_pow.c b/openlibm/src/e_pow.c index e4079839..a8915523 100644 --- a/openlibm/src/e_pow.c +++ b/openlibm/src/e_pow.c @@ -57,6 +57,7 @@ * to produce the hexadecimal values shown. */ +#include #include #include "math_private.h" @@ -310,3 +311,7 @@ __ieee754_pow(double x, double y) else SET_HIGH_WORD(z,j); return s*z; } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(pow, powl); +#endif diff --git a/openlibm/src/e_powf.c b/openlibm/src/e_powf.c index 84b5692f..9527ef0b 100644 --- a/openlibm/src/e_powf.c +++ b/openlibm/src/e_powf.c @@ -25,6 +25,9 @@ bp[] = {1.0, 1.5,}, dp_h[] = { 0.0, 5.84960938e-01,}, /* 0x3f15c000 */ dp_l[] = { 0.0, 1.56322085e-06,}, /* 0x35d1cfdc */ zero = 0.0, +half = 0.5, +qrtr = 0.25, +thrd = 3.33333343e-01, /* 0x3eaaaaab */ one = 1.0, two = 2.0, two24 = 16777216.0, /* 0x4b800000 */ @@ -74,7 +77,7 @@ __ieee754_powf(float x, float y) /* y!=zero: result is NaN if either arg is NaN */ if(ix > 0x7f800000 || iy > 0x7f800000) - return (x+0.0F)+(y+0.0F); + return nan_mix(x, y); /* determine if y is an odd int when x < 0 * yisint = 0 ... y is not an integer @@ -103,15 +106,10 @@ __ieee754_powf(float x, float y) if(iy==0x3f800000) { /* y is +-1 */ if(hy<0) return one/x; else return x; } - if(hy==0x40000000) return x*x; /* y is 2 */ - if(hy==0x40400000) return x*x*x; /* y is 3 */ - if(hy==0x40800000) { /* y is 4 */ - u = x*x; - return u*u; - } - if(hy==0x3f000000) { /* y is 0.5 */ + if(hy==0x40000000) return x*x; /* y is 2 */ + if(hy==0x3f000000) { /* y is 0.5 */ if(hx>=0) /* x >= +0 */ - return __ieee754_sqrtf(x); + return __ieee754_sqrtf(x); } ax = fabsf(x); @@ -139,12 +137,12 @@ __ieee754_powf(float x, float y) /* |y| is huge */ if(iy>0x4d000000) { /* if |y| > 2**27 */ /* over/underflow if x is not close to one */ - if(ix<0x3f7ffff8) return (hy<0)? sn*huge*huge:sn*tiny*tiny; + if(ix<0x3f7ffff6) return (hy<0)? sn*huge*huge:sn*tiny*tiny; if(ix>0x3f800007) return (hy>0)? sn*huge*huge:sn*tiny*tiny; /* now |1-x| is tiny <= 2**-20, suffice to compute log(x) by x-x^2/2+x^3/3-x^4/4 */ t = ax-1; /* t has 20 trailing zeros */ - w = (t*t)*((float)0.5-t*((float)0.333333333333-t*(float)0.25)); + w = (t*t)*(half-t*(thrd-t*qrtr)); u = ivln2_h*t; /* ivln2_h has 16 sig. bits */ v = t*ivln2_l-w*ivln2; t1 = u+v; @@ -183,10 +181,10 @@ __ieee754_powf(float x, float y) r = s2*s2*(L1+s2*(L2+s2*(L3+s2*(L4+s2*(L5+s2*L6))))); r += s_l*(s_h+s); s2 = s_h*s_h; - t_h = (float)3.0+s2+r; + t_h = 3+s2+r; GET_FLOAT_WORD(is,t_h); SET_FLOAT_WORD(t_h,is&0xfffff000); - t_l = r-((t_h-(float)3.0)-s2); + t_l = r-((t_h-3)-s2); /* u+v = s*(1+...) */ u = s_h*t_h; v = s_l*t_h+t_l*s; @@ -198,7 +196,7 @@ __ieee754_powf(float x, float y) z_h = cp_h*p_h; /* cp_h+cp_l = 2/(3*log2) */ z_l = cp_l*p_h+p_l*cp+dp_l[k]; /* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */ - t = (float)n; + t = n; t1 = (((z_h+z_l)+dp_h[k])+t); GET_FLOAT_WORD(is,t1); SET_FLOAT_WORD(t1,is&0xfffff000); diff --git a/openlibm/src/e_remainder.c b/openlibm/src/e_remainder.c index bc9d9bf8..a72631c4 100644 --- a/openlibm/src/e_remainder.c +++ b/openlibm/src/e_remainder.c @@ -75,5 +75,5 @@ __ieee754_remainder(double x, double p) } #if LDBL_MANT_DIG == 53 -__weak_reference(remainder, remainderl); +openlibm_weak_reference(remainder, remainderl); #endif diff --git a/openlibm/src/e_sinh.c b/openlibm/src/e_sinh.c index e6ca6bca..7f3a2bff 100644 --- a/openlibm/src/e_sinh.c +++ b/openlibm/src/e_sinh.c @@ -32,6 +32,7 @@ * only sinh(0)=0 is exact for finite x. */ +#include #include #include "math_private.h" @@ -72,3 +73,7 @@ __ieee754_sinh(double x) /* |x| > overflowthresold, sinh(x) overflow */ return x*shuge; } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(sinh, sinhl); +#endif diff --git a/openlibm/src/e_sqrt.c b/openlibm/src/e_sqrt.c index 01c71044..2eb4a1a6 100644 --- a/openlibm/src/e_sqrt.c +++ b/openlibm/src/e_sqrt.c @@ -189,7 +189,7 @@ __ieee754_sqrt(double x) } #if (LDBL_MANT_DIG == 53) -__weak_reference(sqrt, sqrtl); +openlibm_weak_reference(sqrt, sqrtl); #endif /* diff --git a/openlibm/src/fpmath.h b/openlibm/src/fpmath.h index 58b5382b..eb824d70 100644 --- a/openlibm/src/fpmath.h +++ b/openlibm/src/fpmath.h @@ -37,8 +37,16 @@ #else #include "i386_fpmath.h" #endif -#elif defined(__powerpc__) +#elif defined(__powerpc__) || defined(__POWERPC__) #include "powerpc_fpmath.h" +#elif defined(__mips__) +#include "mips_fpmath.h" +#elif defined(__s390__) +#include "s390_fpmath.h" +#elif defined(__riscv) +#include "riscv_fpmath.h" +#elif defined(__loongarch64) +#include "loongarch64_fpmath.h" #endif /* Definitions provided directly by GCC and Clang. */ diff --git a/openlibm/src/loongarch64_fpmath.h b/openlibm/src/loongarch64_fpmath.h new file mode 100644 index 00000000..31ea1310 --- /dev/null +++ b/openlibm/src/loongarch64_fpmath.h @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2023 Yifan An + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include + +union IEEEl2bits { + long double e; + struct { + uint64_t manl :64; + uint64_t manh :48; + unsigned int exp :15; + unsigned int sign :1; + } bits; + struct { + uint64_t manl :64; + uint64_t manh :48; + unsigned int expsign :16; + } xbits; +}; + +#define LDBL_NBIT 0 +#define LDBL_IMPLICIT_NBIT +#define mask_nbit_l(u) ((void)0) + +#define LDBL_MANH_SIZE 48 +#define LDBL_MANL_SIZE 64 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)((u).bits.manl >> 32); \ + (a)[2] = (uint32_t)(u).bits.manh; \ + (a)[3] = (uint32_t)((u).bits.manh >> 32); \ +} while(0) diff --git a/openlibm/src/math_private.h b/openlibm/src/math_private.h index 5c980460..15a27b28 100644 --- a/openlibm/src/math_private.h +++ b/openlibm/src/math_private.h @@ -18,7 +18,7 @@ #define _MATH_PRIVATE_H_ #include - +#include #include "cdefs-compat.h" #include "types-compat.h" #include "fpmath.h" @@ -203,10 +203,9 @@ do { \ } while (0) -//VBS +#ifndef __FreeBSD__ #define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval)) - -/* VBS +#else #ifdef FLT_EVAL_METHOD // Attempt to get strict C99 semantics for assignment with non-C99 compilers. #if FLT_EVAL_METHOD == 0 || __GNUC__ == 0 @@ -215,7 +214,7 @@ do { \ #define STRICT_ASSIGN(type, lval, rval) do { \ volatile type __lval; \ \ - if (sizeof(type) >= sizeof(double)) \ + if (sizeof(type) >= sizeof(long double)) \ (lval) = (rval); \ else { \ __lval = (rval); \ @@ -224,13 +223,31 @@ do { \ } while (0) #endif #endif -*/ +#endif /* * Common routine to process the arguments to nan(), nanf(), and nanl(). */ void __scan_nan(u_int32_t *__words, int __num_words, const char *__s); +/* + * Mix 1 or 2 NaNs. First add 0 to each arg. This normally just turns + * signaling NaNs into quiet NaNs by setting a quiet bit. We do this + * because we want to never return a signaling NaN, and also because we + * don't want the quiet bit to affect the result. Then mix the converted + * args using addition. The result is typically the arg whose mantissa + * bits (considered as in integer) are largest. + * + * Technical complications: the result in bits might depend on the precision + * and/or on compiler optimizations, especially when different register sets + * are used for different precisions. Try to make the result not depend on + * at least the precision by always doing the main mixing step in long double + * precision. Try to reduce dependencies on optimizations by adding the + * the 0's in different precisions (unless everything is in long double + * precision). + */ +#define nan_mix(x, y) (((x) + 0.0L) + ((y) + 0)) + #ifdef __GNUCLIKE_ASM /* Asm versions of some functions. */ @@ -355,16 +372,4 @@ long double __kernel_sinl(long double, long double, int); long double __kernel_cosl(long double, long double); long double __kernel_tanl(long double, long double, int); -#undef OLM_DLLEXPORT -#ifdef _WIN32 -# ifdef IMPORT_EXPORTS -# define OLM_DLLEXPORT __declspec(dllimport) -# else -# define OLM_DLLEXPORT __declspec(dllexport) -# endif -#else -#define OLM_DLLEXPORT __attribute__ ((visibility("default"))) -#endif - - #endif /* !_MATH_PRIVATE_H_ */ diff --git a/openlibm/src/mips_fpmath.h b/openlibm/src/mips_fpmath.h new file mode 100644 index 00000000..50f119f3 --- /dev/null +++ b/openlibm/src/mips_fpmath.h @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +union IEEEl2bits { + long double e; + struct { +#ifndef __MIPSEB__ + unsigned int manl :32; + unsigned int manh :20; + unsigned int exp :11; + unsigned int sign :1; +#else + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; +#endif + } bits; +}; + +#define LDBL_NBIT 0 +#define mask_nbit_l(u) ((void)0) +#define LDBL_IMPLICIT_NBIT + +#define LDBL_MANH_SIZE 20 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) + diff --git a/openlibm/src/riscv_fpmath.h b/openlibm/src/riscv_fpmath.h new file mode 100644 index 00000000..cfa85ff2 --- /dev/null +++ b/openlibm/src/riscv_fpmath.h @@ -0,0 +1,58 @@ +/*- + * Copyright (c) 2002, 2003 David Schultz + * Copyright (c) 2014 The FreeBSD Foundation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD: head/lib/libc/riscv/_fpmath.h 362788 2020-06-29 19:30:35Z mhorne $ + */ + +union IEEEl2bits { + long double e; + struct { + unsigned long manl :64; + unsigned long manh :48; + unsigned int exp :15; + unsigned int sign :1; + } bits; + struct { + unsigned long manl :64; + unsigned long manh :48; + unsigned int expsign :16; + } xbits; +}; + +#define LDBL_NBIT 0 +#define LDBL_IMPLICIT_NBIT +#define mask_nbit_l(u) ((void)0) + +#define LDBL_MANH_SIZE 48 +#define LDBL_MANL_SIZE 64 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)((u).bits.manl >> 32); \ + (a)[2] = (uint32_t)(u).bits.manh; \ + (a)[3] = (uint32_t)((u).bits.manh >> 32); \ +} while(0) + diff --git a/openlibm/src/s390_fpmath.h b/openlibm/src/s390_fpmath.h new file mode 100644 index 00000000..1e7787c0 --- /dev/null +++ b/openlibm/src/s390_fpmath.h @@ -0,0 +1,51 @@ +/*- + * Copyright (c) 2016 Dan Horák + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + * cloned from powerpc_fpmath.h + */ + +union IEEEl2bits { + long double e; + struct { + unsigned int sign :1; + unsigned int exp :11; + unsigned int manh :20; + unsigned int manl :32; + } bits; +}; + +#define mask_nbit_l(u) ((void)0) +#define LDBL_IMPLICIT_NBIT +#define LDBL_NBIT 0 + +#define LDBL_MANH_SIZE 20 +#define LDBL_MANL_SIZE 32 + +#define LDBL_TO_ARRAY32(u, a) do { \ + (a)[0] = (uint32_t)(u).bits.manl; \ + (a)[1] = (uint32_t)(u).bits.manh; \ +} while(0) diff --git a/openlibm/src/s_asinh.c b/openlibm/src/s_asinh.c index 1f9bc09d..ca7937c3 100644 --- a/openlibm/src/s_asinh.c +++ b/openlibm/src/s_asinh.c @@ -24,6 +24,7 @@ * := sign(x)*log1p(|x| + x^2/(1 + sqrt(1+x^2))) */ +#include #include #include "math_private.h" @@ -55,3 +56,7 @@ asinh(double x) } if(hx>0) return w; else return -w; } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(asinh, asinhl); +#endif diff --git a/openlibm/src/s_atan.c b/openlibm/src/s_atan.c index f87e4866..23a29490 100644 --- a/openlibm/src/s_atan.c +++ b/openlibm/src/s_atan.c @@ -120,5 +120,5 @@ atan(double x) } #if LDBL_MANT_DIG == 53 -__weak_reference(atan, atanl); +openlibm_weak_reference(atan, atanl); #endif diff --git a/openlibm/src/s_cabs.c b/openlibm/src/s_cabs.c index f1635820..481632ae 100644 --- a/openlibm/src/s_cabs.c +++ b/openlibm/src/s_cabs.c @@ -19,6 +19,8 @@ #include #include +#include "math_private.h" + double cabs(double complex z) { @@ -26,5 +28,5 @@ cabs(double complex z) } #if LDBL_MANT_DIG == DBL_MANT_DIG -__strong_alias(cabsl, cabs); +openlibm_strong_reference(cabs, cabsl); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/openlibm/src/s_cacos.c b/openlibm/src/s_cacos.c index 9a8e7fb7..e29717b0 100644 --- a/openlibm/src/s_cacos.c +++ b/openlibm/src/s_cacos.c @@ -50,6 +50,8 @@ #include #include +#include "math_private.h" + double complex cacos(double complex z) { @@ -61,5 +63,5 @@ cacos(double complex z) } #if LDBL_MANT_DIG == DBL_MANT_DIG -__strong_alias(cacosl, cacos); +openlibm_strong_reference(cacos, cacosl); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/openlibm/src/s_cacosh.c b/openlibm/src/s_cacosh.c index 244f437f..f16c14ce 100644 --- a/openlibm/src/s_cacosh.c +++ b/openlibm/src/s_cacosh.c @@ -46,6 +46,8 @@ #include #include +#include "math_private.h" + double complex cacosh(double complex z) { @@ -56,5 +58,5 @@ cacosh(double complex z) } #if LDBL_MANT_DIG == DBL_MANT_DIG -__strong_alias(cacoshl, cacosh); +openlibm_strong_reference(cacosh, cacoshl); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/openlibm/src/s_casin.c b/openlibm/src/s_casin.c index 82939f15..4e5daaa7 100644 --- a/openlibm/src/s_casin.c +++ b/openlibm/src/s_casin.c @@ -53,6 +53,8 @@ #include #include +#include "math_private.h" + double complex casin(double complex z) { @@ -130,5 +132,5 @@ casin(double complex z) } #if LDBL_MANT_DIG == DBL_MANT_DIG -__strong_alias(casinl, casin); +openlibm_strong_reference(casin, casinl); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/openlibm/src/s_casinh.c b/openlibm/src/s_casinh.c index d3ca8b00..4b1154d9 100644 --- a/openlibm/src/s_casinh.c +++ b/openlibm/src/s_casinh.c @@ -46,6 +46,8 @@ #include #include +#include "math_private.h" + double complex casinh(double complex z) { @@ -56,5 +58,5 @@ casinh(double complex z) } #if LDBL_MANT_DIG == DBL_MANT_DIG -__strong_alias(casinhl, casinh); +openlibm_strong_reference(casinh, casinhl); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/openlibm/src/s_catan.c b/openlibm/src/s_catan.c index 2e8bdbba..9ee3dbb9 100644 --- a/openlibm/src/s_catan.c +++ b/openlibm/src/s_catan.c @@ -66,6 +66,8 @@ #include #include +#include "math_private.h" + #define MAXNUM 1.0e308 static const double DP1 = 3.14159265160560607910E0; @@ -127,5 +129,5 @@ catan(double complex z) } #if LDBL_MANT_DIG == DBL_MANT_DIG -__strong_alias(catanl, catan); +openlibm_strong_reference(catan, catanl); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/openlibm/src/s_catanh.c b/openlibm/src/s_catanh.c index f4391ee8..3e3eeafe 100644 --- a/openlibm/src/s_catanh.c +++ b/openlibm/src/s_catanh.c @@ -46,6 +46,8 @@ #include #include +#include "math_private.h" + double complex catanh(double complex z) { @@ -56,5 +58,5 @@ catanh(double complex z) } #if LDBL_MANT_DIG == DBL_MANT_DIG -__strong_alias(catanhl, catanh); +openlibm_strong_reference(catanh, catanhl); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/openlibm/src/s_cbrt.c b/openlibm/src/s_cbrt.c index dd3c1415..b6316ada 100644 --- a/openlibm/src/s_cbrt.c +++ b/openlibm/src/s_cbrt.c @@ -114,5 +114,5 @@ cbrt(double x) } #if (LDBL_MANT_DIG == 53) -__weak_reference(cbrt, cbrtl); +openlibm_weak_reference(cbrt, cbrtl); #endif diff --git a/openlibm/src/s_ccos.c b/openlibm/src/s_ccos.c index 48f2b7b9..faafdb04 100644 --- a/openlibm/src/s_ccos.c +++ b/openlibm/src/s_ccos.c @@ -53,6 +53,8 @@ #include #include +#include "math_private.h" + /* calculate cosh and sinh */ static void @@ -85,5 +87,5 @@ ccos(double complex z) } #if LDBL_MANT_DIG == DBL_MANT_DIG -__strong_alias(ccosl, ccos); +openlibm_strong_reference(ccos, ccosl); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/openlibm/src/s_ceil.c b/openlibm/src/s_ceil.c index bdac17f1..9c70a976 100644 --- a/openlibm/src/s_ceil.c +++ b/openlibm/src/s_ceil.c @@ -73,5 +73,5 @@ ceil(double x) } #if LDBL_MANT_DIG == 53 -__weak_reference(ceil, ceill); +openlibm_weak_reference(ceil, ceill); #endif diff --git a/openlibm/src/s_clog.c b/openlibm/src/s_clog.c index 30ea5eaa..6412df78 100644 --- a/openlibm/src/s_clog.c +++ b/openlibm/src/s_clog.c @@ -38,7 +38,7 @@ * If z = x + iy, r = sqrt( x**2 + y**2 ), * then * w = log(r) + i arctan(y/x). - * + * * The arctangent ranges from -PI to +PI. * * @@ -58,6 +58,8 @@ #include #include +#include "math_private.h" + double complex clog(double complex z) { @@ -73,5 +75,5 @@ clog(double complex z) } #if LDBL_MANT_DIG == DBL_MANT_DIG -__strong_alias(clogl, clog); +openlibm_strong_reference(clog, clogl); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/openlibm/src/s_cos.c b/openlibm/src/s_cos.c index ea84163c..9896bd82 100644 --- a/openlibm/src/s_cos.c +++ b/openlibm/src/s_cos.c @@ -85,5 +85,5 @@ cos(double x) } #if (LDBL_MANT_DIG == 53) -__weak_reference(cos, cosl); +openlibm_weak_reference(cos, cosl); #endif diff --git a/openlibm/src/s_cpow.c b/openlibm/src/s_cpow.c index d99621f6..dae6251f 100644 --- a/openlibm/src/s_cpow.c +++ b/openlibm/src/s_cpow.c @@ -74,5 +74,5 @@ cpow(double complex a, double complex z) } #if LDBL_MANT_DIG == DBL_MANT_DIG -__strong_alias(cpowl, cpow); +openlibm_strong_reference(cpow, cpowl); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/openlibm/src/s_cproj.c b/openlibm/src/s_cproj.c index 89dfc55d..b9faa240 100644 --- a/openlibm/src/s_cproj.c +++ b/openlibm/src/s_cproj.c @@ -43,5 +43,5 @@ cproj(double complex z) } #if LDBL_MANT_DIG == 53 -__weak_reference(cproj, cprojl); +openlibm_weak_reference(cproj, cprojl); #endif diff --git a/openlibm/src/s_csin.c b/openlibm/src/s_csin.c index 8560e0b1..a905991e 100644 --- a/openlibm/src/s_csin.c +++ b/openlibm/src/s_csin.c @@ -55,6 +55,8 @@ #include #include +#include "math_private.h" + /* calculate cosh and sinh */ static void @@ -87,5 +89,5 @@ csin(double complex z) } #if LDBL_MANT_DIG == DBL_MANT_DIG -__strong_alias(csinl, csin); +openlibm_strong_reference(csin, csinl); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/openlibm/src/s_csqrt.c b/openlibm/src/s_csqrt.c index 105592fc..9cf42556 100644 --- a/openlibm/src/s_csqrt.c +++ b/openlibm/src/s_csqrt.c @@ -110,5 +110,5 @@ csqrt(double complex z) } #if LDBL_MANT_DIG == 53 -__weak_reference(csqrt, csqrtl); +openlibm_weak_reference(csqrt, csqrtl); #endif diff --git a/openlibm/src/s_ctan.c b/openlibm/src/s_ctan.c index 5082e392..94200959 100644 --- a/openlibm/src/s_ctan.c +++ b/openlibm/src/s_ctan.c @@ -60,6 +60,8 @@ #include #include +#include "math_private.h" + #define MACHEP 1.1e-16 #define MAXNUM 1.0e308 @@ -153,5 +155,5 @@ ctan(double complex z) } #if LDBL_MANT_DIG == DBL_MANT_DIG -__strong_alias(ctanl, ctan); +openlibm_strong_reference(ctan, ctanl); #endif /* LDBL_MANT_DIG == DBL_MANT_DIG */ diff --git a/openlibm/src/s_erf.c b/openlibm/src/s_erf.c index 33ef9130..67068c4c 100644 --- a/openlibm/src/s_erf.c +++ b/openlibm/src/s_erf.c @@ -107,6 +107,7 @@ * erfc/erf(NaN) is NaN */ +#include #include #include "math_private.h" @@ -299,3 +300,8 @@ erfc(double x) if(hx>0) return tiny*tiny; else return two-tiny; } } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(erf, erfl); +openlibm_weak_reference(erfc, erfcl); +#endif diff --git a/openlibm/src/s_exp2.c b/openlibm/src/s_exp2.c index e5faf7fc..d643dbb3 100644 --- a/openlibm/src/s_exp2.c +++ b/openlibm/src/s_exp2.c @@ -392,5 +392,5 @@ exp2(double x) } #if (LDBL_MANT_DIG == 53) -__weak_reference(exp2, exp2l); +openlibm_weak_reference(exp2, exp2l); #endif diff --git a/openlibm/src/s_expm1.c b/openlibm/src/s_expm1.c index 369598d6..57987146 100644 --- a/openlibm/src/s_expm1.c +++ b/openlibm/src/s_expm1.c @@ -215,3 +215,7 @@ expm1(double x) } return y; } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(expm1, expm1l); +#endif diff --git a/openlibm/src/s_fdim.c b/openlibm/src/s_fdim.c index 1781f728..2f05347c 100644 --- a/openlibm/src/s_fdim.c +++ b/openlibm/src/s_fdim.c @@ -43,4 +43,6 @@ fn(type x, type y) \ DECL(double, fdim) DECL(float, fdimf) +#ifdef OLM_LONG_DOUBLE DECL(long double, fdiml) +#endif diff --git a/openlibm/src/s_floor.c b/openlibm/src/s_floor.c index 1d67a21d..4a44bd5f 100644 --- a/openlibm/src/s_floor.c +++ b/openlibm/src/s_floor.c @@ -74,5 +74,5 @@ floor(double x) } #if LDBL_MANT_DIG == 53 -__weak_reference(floor, floorl); +openlibm_weak_reference(floor, floorl); #endif diff --git a/openlibm/src/s_fma.c b/openlibm/src/s_fma.c index 798e4264..63e529e5 100644 --- a/openlibm/src/s_fma.c +++ b/openlibm/src/s_fma.c @@ -280,5 +280,5 @@ fma(double x, double y, double z) } #if (LDBL_MANT_DIG == 53) -__weak_reference(fma, fmal); +openlibm_weak_reference(fma, fmal); #endif diff --git a/openlibm/src/s_fpclassify.c b/openlibm/src/s_fpclassify.c index 558fb55c..2b552e17 100644 --- a/openlibm/src/s_fpclassify.c +++ b/openlibm/src/s_fpclassify.c @@ -72,7 +72,7 @@ __fpclassifyf(float f) } } -#ifdef LONG_DOUBLE +#ifdef OLM_LONG_DOUBLE OLM_DLLEXPORT int __fpclassifyl(long double e) { diff --git a/openlibm/src/s_frexp.c b/openlibm/src/s_frexp.c index 46367a48..0385acfb 100644 --- a/openlibm/src/s_frexp.c +++ b/openlibm/src/s_frexp.c @@ -52,5 +52,5 @@ frexp(double x, int *eptr) } #if (LDBL_MANT_DIG == 53) -__weak_reference(frexp, frexpl); +openlibm_weak_reference(frexp, frexpl); #endif diff --git a/openlibm/src/s_isfinite.c b/openlibm/src/s_isfinite.c index 504c2b8b..7c118763 100644 --- a/openlibm/src/s_isfinite.c +++ b/openlibm/src/s_isfinite.c @@ -49,7 +49,7 @@ __isfinitef(float f) return (u.bits.exp != 255); } -#ifdef LONG_DOUBLE +#ifdef OLM_LONG_DOUBLE OLM_DLLEXPORT int __isfinitel(long double e) { diff --git a/openlibm/src/s_isinf.c b/openlibm/src/s_isinf.c index c013c918..02eaff36 100644 --- a/openlibm/src/s_isinf.c +++ b/openlibm/src/s_isinf.c @@ -51,7 +51,7 @@ __isinff(float f) return (u.bits.exp == 255 && u.bits.man == 0); } -#ifdef LONG_DOUBLE +#ifdef OLM_LONG_DOUBLE OLM_DLLEXPORT int __isinfl(long double e) { @@ -63,4 +63,4 @@ __isinfl(long double e) } #endif -__weak_reference(__isinff, isinff); +openlibm_weak_reference(__isinff, isinff); diff --git a/openlibm/src/s_isnan.c b/openlibm/src/s_isnan.c index b68aa5b5..b9066aa5 100644 --- a/openlibm/src/s_isnan.c +++ b/openlibm/src/s_isnan.c @@ -52,7 +52,7 @@ __isnanf(float f) return (u.bits.exp == 255 && u.bits.man != 0); } -#ifdef LONG_DOUBLE +#ifdef OLM_LONG_DOUBLE OLM_DLLEXPORT int __isnanl(long double e) { @@ -64,4 +64,4 @@ __isnanl(long double e) } #endif -__weak_reference(__isnanf, isnanf); +openlibm_weak_reference(__isnanf, isnanf); diff --git a/openlibm/src/s_isnormal.c b/openlibm/src/s_isnormal.c index b6f6dd29..3c721d72 100644 --- a/openlibm/src/s_isnormal.c +++ b/openlibm/src/s_isnormal.c @@ -49,7 +49,7 @@ __isnormalf(float f) return (u.bits.exp != 0 && u.bits.exp != 255); } -#ifdef LONG_DOUBLE +#ifdef OLM_LONG_DOUBLE OLM_DLLEXPORT int __isnormall(long double e) { diff --git a/openlibm/src/s_log1p.c b/openlibm/src/s_log1p.c index aa36fcdf..1921b6a3 100644 --- a/openlibm/src/s_log1p.c +++ b/openlibm/src/s_log1p.c @@ -173,3 +173,7 @@ log1p(double x) if(k==0) return f-(hfsq-s*(hfsq+R)); else return k*ln2_hi-((hfsq-(s*(hfsq+R)+(k*ln2_lo+c)))-f); } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(log1p, log1pl); +#endif diff --git a/openlibm/src/s_logb.c b/openlibm/src/s_logb.c index 6395dd6b..116b6963 100644 --- a/openlibm/src/s_logb.c +++ b/openlibm/src/s_logb.c @@ -45,5 +45,5 @@ logb(double x) } #if (LDBL_MANT_DIG == 53) -__weak_reference(logb, logbl); +openlibm_weak_reference(logb, logbl); #endif diff --git a/openlibm/src/s_nan.c b/openlibm/src/s_nan.c index 3539a82f..dd1c5afd 100644 --- a/openlibm/src/s_nan.c +++ b/openlibm/src/s_nan.c @@ -120,5 +120,5 @@ nanf(const char *s) } #if (LDBL_MANT_DIG == 53) -__weak_reference(nan, nanl); +openlibm_weak_reference(nan, nanl); #endif diff --git a/openlibm/src/s_nextafter.c b/openlibm/src/s_nextafter.c index 2fbf2ed6..8b2ea05f 100644 --- a/openlibm/src/s_nextafter.c +++ b/openlibm/src/s_nextafter.c @@ -77,7 +77,7 @@ nextafter(double x, double y) } #if (LDBL_MANT_DIG == 53) -__weak_reference(nextafter, nexttoward); -__weak_reference(nextafter, nexttowardl); -__weak_reference(nextafter, nextafterl); +openlibm_weak_reference(nextafter, nexttoward); +openlibm_weak_reference(nextafter, nexttowardl); +openlibm_weak_reference(nextafter, nextafterl); #endif diff --git a/openlibm/src/s_nextafterl.c b/openlibm/src/s_nextafterl.c index d00cd652..bb73141e 100644 --- a/openlibm/src/s_nextafterl.c +++ b/openlibm/src/s_nextafterl.c @@ -77,4 +77,4 @@ nextafterl(long double x, long double y) return ux.e; } -__strong_reference(nextafterl, nexttowardl); +openlibm_strong_reference(nextafterl, nexttowardl); diff --git a/openlibm/src/s_nexttowardf.c b/openlibm/src/s_nexttowardf.c index 5676995b..bf508629 100644 --- a/openlibm/src/s_nexttowardf.c +++ b/openlibm/src/s_nexttowardf.c @@ -20,7 +20,7 @@ #define LDBL_INFNAN_EXP (LDBL_MAX_EXP * 2 - 1) -#ifdef LONG_DOUBLE +#ifdef OLM_LONG_DOUBLE OLM_DLLEXPORT float nexttowardf(float x, long double y) { diff --git a/openlibm/src/s_remquo.c b/openlibm/src/s_remquo.c index 13375c31..afc325d9 100644 --- a/openlibm/src/s_remquo.c +++ b/openlibm/src/s_remquo.c @@ -51,7 +51,7 @@ remquo(double x, double y, int *quo) goto fixup; /* |x|<|y| return x or x-y */ } if(lx==ly) { - *quo = 1; + *quo = (sxy ? -1 : 1); return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/ } } @@ -114,6 +114,7 @@ remquo(double x, double y, int *quo) /* convert back to floating value and restore the sign */ if((hx|lx)==0) { /* return sign(x)*0 */ + q &= 0x7fffffff; *quo = (sxy ? -q : q); return Zero[(u_int32_t)sx>>31]; } @@ -129,9 +130,9 @@ remquo(double x, double y, int *quo) lx = (lx>>n)|((u_int32_t)hx<<(32-n)); hx >>= n; } else if (n<=31) { - lx = (hx<<(32-n))|(lx>>n); hx = sx; + lx = (hx<<(32-n))|(lx>>n); hx = 0; } else { - lx = hx>>(n-32); hx = sx; + lx = hx>>(n-32); hx = 0; } } fixup: @@ -154,5 +155,5 @@ remquo(double x, double y, int *quo) } #if LDBL_MANT_DIG == 53 -__weak_reference(remquo, remquol); +openlibm_weak_reference(remquo, remquol); #endif diff --git a/openlibm/src/s_remquof.c b/openlibm/src/s_remquof.c index 7ef0f723..1983ed56 100644 --- a/openlibm/src/s_remquof.c +++ b/openlibm/src/s_remquof.c @@ -47,7 +47,7 @@ remquof(float x, float y, int *quo) q = 0; goto fixup; /* |x|<|y| return x or x-y */ } else if(hx==hy) { - *quo = 1; + *quo = (sxy ? -1 : 1); return Zero[(u_int32_t)sx>>31]; /* |x|=|y| return x*0*/ } @@ -89,6 +89,7 @@ remquof(float x, float y, int *quo) /* convert back to floating value and restore the sign */ if(hx==0) { /* return sign(x)*0 */ + q &= 0x7fffffff; *quo = (sxy ? -q : q); return Zero[(u_int32_t)sx>>31]; } diff --git a/openlibm/src/s_remquol.c b/openlibm/src/s_remquol.c index ebde9993..b610b671 100644 --- a/openlibm/src/s_remquol.c +++ b/openlibm/src/s_remquol.c @@ -96,7 +96,7 @@ remquol(long double x, long double y, int *quo) goto fixup; /* |x|<|y| return x or x-y */ } if(ux.bits.manh==uy.bits.manh && ux.bits.manl==uy.bits.manl) { - *quo = 1; + *quo = (sxy ? -1 : 1); return Zero[sx]; /* |x|=|y| return x*0*/ } } @@ -138,6 +138,7 @@ remquol(long double x, long double y, int *quo) /* convert back to floating value and restore the sign */ if((hx|lx)==0) { /* return sign(x)*0 */ + q &= 0x7fffffff; *quo = (sxy ? -q : q); return Zero[sx]; } diff --git a/openlibm/src/s_rint.c b/openlibm/src/s_rint.c index f2d8c0e7..f81e6925 100644 --- a/openlibm/src/s_rint.c +++ b/openlibm/src/s_rint.c @@ -88,5 +88,5 @@ rint(double x) } #if (LDBL_MANT_DIG == 53) -__weak_reference(rint, rintl); +openlibm_weak_reference(rint, rintl); #endif diff --git a/openlibm/src/s_scalbln.c b/openlibm/src/s_scalbln.c index 978b5237..8239db56 100644 --- a/openlibm/src/s_scalbln.c +++ b/openlibm/src/s_scalbln.c @@ -62,6 +62,7 @@ scalblnf (float x, long n) return (scalbnf(x, in)); } +#ifdef OLM_LONG_DOUBLE OLM_DLLEXPORT long double scalblnl (long double x, long n) { @@ -76,3 +77,4 @@ scalblnl (long double x, long n) } return (scalbnl(x, (int)n)); } +#endif diff --git a/openlibm/src/s_scalbn.c b/openlibm/src/s_scalbn.c index 4ab59cae..dc3a0cfd 100644 --- a/openlibm/src/s_scalbn.c +++ b/openlibm/src/s_scalbn.c @@ -59,8 +59,8 @@ scalbn (double x, int n) } #if (LDBL_MANT_DIG == 53) -__weak_reference(scalbn, ldexpl); -__weak_reference(scalbn, scalbnl); +openlibm_weak_reference(scalbn, ldexpl); +openlibm_weak_reference(scalbn, scalbnl); #endif -__strong_reference(scalbn, ldexp); +openlibm_strong_reference(scalbn, ldexp); diff --git a/openlibm/src/s_scalbnf.c b/openlibm/src/s_scalbnf.c index 3e8c4713..930ab8fa 100644 --- a/openlibm/src/s_scalbnf.c +++ b/openlibm/src/s_scalbnf.c @@ -54,4 +54,4 @@ scalbnf (float x, int n) return x*twom25; } -__strong_reference(scalbnf, ldexpf); +openlibm_strong_reference(scalbnf, ldexpf); diff --git a/openlibm/src/s_scalbnl.c b/openlibm/src/s_scalbnl.c index d41cd026..7732944f 100644 --- a/openlibm/src/s_scalbnl.c +++ b/openlibm/src/s_scalbnl.c @@ -67,4 +67,4 @@ scalbnl (long double x, int n) return u.e*0x1p-128; } -__strong_reference(scalbnl, ldexpl); +openlibm_strong_reference(scalbnl, ldexpl); diff --git a/openlibm/src/s_signbit.c b/openlibm/src/s_signbit.c index 3954c411..87f40f27 100644 --- a/openlibm/src/s_signbit.c +++ b/openlibm/src/s_signbit.c @@ -49,7 +49,7 @@ __signbitf(float f) return (u.bits.sign); } -#ifdef LONG_DOUBLE +#ifdef OLM_LONG_DOUBLE OLM_DLLEXPORT int __signbitl(long double e) { diff --git a/openlibm/src/s_sin.c b/openlibm/src/s_sin.c index 3eb0c4a4..cc0a5c6f 100644 --- a/openlibm/src/s_sin.c +++ b/openlibm/src/s_sin.c @@ -85,5 +85,5 @@ sin(double x) } #if (LDBL_MANT_DIG == 53) -__weak_reference(sin, sinl); +openlibm_weak_reference(sin, sinl); #endif diff --git a/openlibm/src/s_sincos.c b/openlibm/src/s_sincos.c index 229d9673..86282356 100644 --- a/openlibm/src/s_sincos.c +++ b/openlibm/src/s_sincos.c @@ -1,5 +1,14 @@ /* @(#)s_sincos.c 5.1 13/07/15 */ -/* +/* See openlibm LICENSE.md for full license details. + * + * ==================================================== + * This file is derived from fdlibm: + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * * ==================================================== * Copyright (C) 2013 Elliot Saba. All rights reserved. * @@ -25,7 +34,7 @@ * Borrow liberally from s_sin.c and s_cos.c, merging * efforts where applicable and returning their values in * appropriate variables, thereby slightly reducing the - * amount of work relative to just calling sin/cos(x) + * amount of work relative to just calling sin/cos(x) * separately * * Special cases: @@ -146,5 +155,5 @@ sincos(double x, double * s, double * c) } #if (LDBL_MANT_DIG == 53) -__weak_reference(sincos, sincosl); +openlibm_weak_reference(sincos, sincosl); #endif diff --git a/openlibm/src/s_sincosf.c b/openlibm/src/s_sincosf.c index 09f35aff..62caaac4 100644 --- a/openlibm/src/s_sincosf.c +++ b/openlibm/src/s_sincosf.c @@ -1,5 +1,14 @@ /* s_sincosf.c -- float version of s_sincos.c * + * ==================================================== + * This file is derived from fdlibm: + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * Developed at SunPro, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * + * ==================================================== * Copyright (C) 2013 Elliot Saba * Developed at the University of Washington * @@ -115,14 +124,14 @@ sincosf(float x, float * s, float * c) { /* |x| ~<= 9*pi/4 */ if(ix<=0x40e231d5) { /* |x| ~> 7*pi/4 */ - if(ix<=0x40afeddf) { + if(ix<=0x40afeddf) { if(hx>0) { __kernel_sincosdf( x - sc3pio2, c, &k_s ); *s = -k_s; } else { __kernel_sincosdf( x + sc3pio2, &k_c, s ); *c = -k_c; - } + } } else { if( hx > 0 ) { @@ -148,7 +157,7 @@ sincosf(float x, float * s, float * c) { case 1: __kernel_sincosdf( -y, c, s ); break; - case 2: + case 2: __kernel_sincosdf( -y, s, &k_c); *c = -k_c; break; diff --git a/openlibm/src/s_tan.c b/openlibm/src/s_tan.c index 07f22443..2b234a2b 100644 --- a/openlibm/src/s_tan.c +++ b/openlibm/src/s_tan.c @@ -79,5 +79,5 @@ tan(double x) } #if (LDBL_MANT_DIG == 53) -__weak_reference(tan, tanl); +openlibm_weak_reference(tan, tanl); #endif diff --git a/openlibm/src/s_tanh.c b/openlibm/src/s_tanh.c index a8d52dae..1fa734d2 100644 --- a/openlibm/src/s_tanh.c +++ b/openlibm/src/s_tanh.c @@ -37,6 +37,7 @@ * only tanh(0)=0 is exact for finite argument. */ +#include #include #include "math_private.h" @@ -76,3 +77,7 @@ tanh(double x) } return (jx>=0)? z: -z; } + +#if (LDBL_MANT_DIG == 53) +openlibm_weak_reference(tanh, tanhl); +#endif diff --git a/openlibm/src/s_trunc.c b/openlibm/src/s_trunc.c index b01bfef9..c460cc92 100644 --- a/openlibm/src/s_trunc.c +++ b/openlibm/src/s_trunc.c @@ -63,5 +63,5 @@ trunc(double x) } #if LDBL_MANT_DIG == 53 -__weak_reference(trunc, truncl); +openlibm_weak_reference(trunc, truncl); #endif diff --git a/openlibm/src/w_cabs.c b/openlibm/src/w_cabs.c index 6b53a60d..6dc9bdee 100644 --- a/openlibm/src/w_cabs.c +++ b/openlibm/src/w_cabs.c @@ -21,5 +21,5 @@ cabs(double complex z) } #if LDBL_MANT_DIG == 53 -__weak_reference(cabs, cabsl); +openlibm_weak_reference(cabs, cabsl); #endif diff --git a/openlibm/test/Makefile b/openlibm/test/Makefile index a7f7cb91..a61ce5a2 100644 --- a/openlibm/test/Makefile +++ b/openlibm/test/Makefile @@ -7,6 +7,8 @@ ifneq ($(OS),WINNT) ifneq ($(OS),Darwin) OPENLIBM_LIB += -Wl,-rpath=$(OPENLIBM_HOME) endif +else # WINNT +CFLAGS_add += -DIMPORT_EXPORTS endif all: test-double test-float # test-double-system test-float-system diff --git a/openlibm/test/libm-test-ulps.h b/openlibm/test/libm-test-ulps.h index 4752bc3e..67a415c0 100644 --- a/openlibm/test/libm-test-ulps.h +++ b/openlibm/test/libm-test-ulps.h @@ -250,5 +250,5 @@ #define DELTA1663 CHOOSE(2, 2, 2, 2, 2, 1) /* yn (10, 0.1) == -0.11831335132045197885e19 */ #define DELTA1664 CHOOSE(7, 6, 3, 7, 6, 3) /* yn (10, 0.7) == -0.42447194260703866924e10 */ #define DELTA1665 CHOOSE(0, 1, 2, 0, 1, 1) /* yn (10, 1.0) == -0.12161801427868918929e9 */ -#define DELTA1666 CHOOSE(1, 3, 1, 1, 2, 1) /* yn (10, 2.0) == -129184.54220803928264 */ +#define DELTA1666 CHOOSE(1, 3, 3, 1, 2, 1) /* yn (10, 2.0) == -129184.54220803928264 */ #define DELTA1667 CHOOSE(0, 2, 1, 0, 2, 1) /* yn (10, 10.0) == -0.35981415218340272205 */ diff --git a/openlibm/test/test-211.c b/openlibm/test/test-211.c new file mode 100644 index 00000000..8bec4e9e --- /dev/null +++ b/openlibm/test/test-211.c @@ -0,0 +1,12 @@ +#include +#include +#include + +int +main() +{ + float x = 0xd.65874p-4f; + float y = 4.0f; + float z = powf (x, y); + assert(z==0x1.f74424p-2); +} diff --git a/openlibm/wasm32/Make.files b/openlibm/wasm32/Make.files new file mode 100644 index 00000000..e69de29b diff --git a/openlibm/wasm32/assert.h b/openlibm/wasm32/assert.h new file mode 100644 index 00000000..5c6205be --- /dev/null +++ b/openlibm/wasm32/assert.h @@ -0,0 +1 @@ +#define assert(x) ((void)0) diff --git a/openlibm/wasm32/float.h b/openlibm/wasm32/float.h new file mode 100644 index 00000000..c82ecbdb --- /dev/null +++ b/openlibm/wasm32/float.h @@ -0,0 +1,33 @@ +#pragma once + +#define FLT_RADIX 2 + +#define FLT_TRUE_MIN 1.40129846432481707092e-45F +#define FLT_MIN 1.17549435082228750797e-38F +#define FLT_MAX 3.40282346638528859812e+38F +#define FLT_EPSILON 1.1920928955078125e-07F + +#define FLT_MANT_DIG 24 +#define FLT_MIN_EXP (-125) +#define FLT_MAX_EXP 128 +#define FLT_HAS_SUBNORM 1 + +#define FLT_DIG 6 +#define FLT_DECIMAL_DIG 9 +#define FLT_MIN_10_EXP (-37) +#define FLT_MAX_10_EXP 38 + +#define DBL_TRUE_MIN 4.94065645841246544177e-324 +#define DBL_MIN 2.22507385850720138309e-308 +#define DBL_MAX 1.79769313486231570815e+308 +#define DBL_EPSILON 2.22044604925031308085e-16 + +#define DBL_MANT_DIG 53 +#define DBL_MIN_EXP (-1021) +#define DBL_MAX_EXP 1024 +#define DBL_HAS_SUBNORM 1 + +#define DBL_DIG 15 +#define DBL_DECIMAL_DIG 17 +#define DBL_MIN_10_EXP (-307) +#define DBL_MAX_10_EXP 308 diff --git a/openlibm/wasm32/limits.h b/openlibm/wasm32/limits.h new file mode 100644 index 00000000..1f8d1248 --- /dev/null +++ b/openlibm/wasm32/limits.h @@ -0,0 +1,9 @@ +#include + +#define INT_MIN INT32_MIN +#define INT_MAX INT32_MAX +#define LONG_MIN INT32_MIN +#define LONG_MAX INT32_MAX +#define LLONG_MIN INT64_MIN +#define LLONG_MAX INT64_MAX + diff --git a/openlibm/wasm32/stdint.h b/openlibm/wasm32/stdint.h new file mode 100644 index 00000000..3996e5b1 --- /dev/null +++ b/openlibm/wasm32/stdint.h @@ -0,0 +1,43 @@ +#pragma once + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +typedef char int8_t; +typedef short int16_t; +typedef int int32_t; +typedef long long int64_t; + +typedef unsigned int uintptr_t; +typedef int intptr_t; + +_Static_assert(sizeof (uint8_t) == 1, "invalid size"); +_Static_assert(sizeof (uint16_t) == 2, "invalid size"); +_Static_assert(sizeof (uint32_t) == 4, "invalid size"); +_Static_assert(sizeof (uint64_t) == 8, "invalid size"); + +_Static_assert(sizeof (int8_t) == 1, "invalid size"); +_Static_assert(sizeof (int16_t) == 2, "invalid size"); +_Static_assert(sizeof (int32_t) == 4, "invalid size"); +_Static_assert(sizeof (int64_t) == 8, "invalid size"); + +_Static_assert(sizeof (uintptr_t) == sizeof (intptr_t), "invalid size"); +_Static_assert(sizeof (uintptr_t) == sizeof (void*), "invalid size"); +_Static_assert(sizeof (uintptr_t) == 4, "invalid size"); + +#define UINT8_MAX 0xFF +#define UINT16_MAX 0xFFFF +#define UINT32_MAX 0xFFFFFFFFUL +#define UINT64_MAX 0xFFFFFFFFFFFFFFFFULL + +#define INT8_MAX 0x7F +#define INT16_MAX 0x7FFF +#define INT32_MAX 0x7FFFFFFF +#define INT64_MAX 0x7FFFFFFFFFFFFFFF + +#define INT8_MIN (-0x80) +#define INT16_MIN (-0x8000) +#define INT32_MIN (-0x80000000L) +#define INT64_MIN (-0x8000000000000000LL)