mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-26 13:01:27 +03:00
Auto merge of #155709 - tgross35:compiler-builtins-sync-2026-04-22, r=tgross35
compiler-builtins subtree update Subtree update of `compiler-builtins` to https://github.com/rust-lang/compiler-builtins/commit/4d3ab8695dcf965be926882c92878b99017bf99b. Created using https://github.com/rust-lang/josh-sync. Closes: https://github.com/rust-lang/rust/pull/155653
This commit is contained in:
@@ -1,5 +1,3 @@
|
||||
# EditorConfig helps developers define and maintain consistent
|
||||
# coding styles between different editors and IDEs
|
||||
# editorconfig.org
|
||||
|
||||
root = true
|
||||
@@ -12,5 +10,5 @@ insert_final_newline = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
|
||||
[*.yml]
|
||||
[*.{yaml,yml}]
|
||||
indent_size = 2
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
$schema: "https://docs.renovatebot.com/renovate-schema.json",
|
||||
extends: [
|
||||
"config:recommended",
|
||||
":maintainLockFilesMonthly",
|
||||
"helpers:pinGitHubActionDigestsToSemver"
|
||||
],
|
||||
packageRules: [
|
||||
{
|
||||
matchCategories: [
|
||||
"rust"
|
||||
],
|
||||
matchJsonata: [
|
||||
"isBreaking != true"
|
||||
],
|
||||
// Disable non-breaking change updates because they
|
||||
// are updated periodically with lockfile maintainance.
|
||||
enabled: false,
|
||||
},
|
||||
{
|
||||
matchManagers: [
|
||||
"github-actions"
|
||||
],
|
||||
// Every month
|
||||
schedule: "* 0 1 * *",
|
||||
groupName: "Github Actions",
|
||||
}
|
||||
],
|
||||
// Receive any update that fixes security vulnerabilities.
|
||||
// We need this because we disabled "patch" updates for Rust.
|
||||
// Note: You need to enable "Dependabot alerts" in "Code security" GitHub
|
||||
// Settings to receive security updates.
|
||||
// See https://docs.renovatebot.com/configuration-options/#vulnerabilityalerts
|
||||
vulnerabilityAlerts: {
|
||||
enabled: true,
|
||||
},
|
||||
}
|
||||
+92
-52
@@ -1,4 +1,5 @@
|
||||
name: CI
|
||||
permissions: {}
|
||||
on:
|
||||
push: { branches: [main] }
|
||||
pull_request:
|
||||
@@ -10,6 +11,7 @@ concurrency:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
LIBM_BUILD_VERBOSE: true
|
||||
RUSTDOCFLAGS: -Dwarnings
|
||||
RUSTFLAGS: -Dwarnings
|
||||
RUST_BACKTRACE: full
|
||||
@@ -28,8 +30,9 @@ jobs:
|
||||
extensive_matrix: ${{ steps.script.outputs.extensive_matrix }}
|
||||
may_skip_libm_ci: ${{ steps.script.outputs.may_skip_libm_ci }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 500
|
||||
- name: Fetch pull request ref
|
||||
run: git fetch origin "$GITHUB_REF:$GITHUB_REF"
|
||||
@@ -42,6 +45,9 @@ jobs:
|
||||
test:
|
||||
name: Build and test
|
||||
timeout-minutes: 60
|
||||
# NOTE: self-hosted riscv64 runners are experimental and may be flaky.
|
||||
# Do not block CI on failures from this platform for now.
|
||||
continue-on-error: ${{ contains(matrix.os, 'self-hosted') }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
@@ -72,6 +78,9 @@ jobs:
|
||||
os: ubuntu-24.04
|
||||
- target: powerpc64le-unknown-linux-gnu
|
||||
os: ubuntu-24.04-ppc64le
|
||||
# FIXME(ci): re-enable these once more capacity is avialable
|
||||
# - target: riscv64gc-unknown-linux-gnu
|
||||
# os: ["self-hosted", "linux", "riscv64"]
|
||||
- target: riscv64gc-unknown-linux-gnu
|
||||
os: ubuntu-24.04
|
||||
- target: s390x-unknown-linux-gnu
|
||||
@@ -104,53 +113,58 @@ jobs:
|
||||
needs: [calculate_vars]
|
||||
env:
|
||||
BUILD_ONLY: ${{ matrix.build_only }}
|
||||
JOB_TARGET: ${{ matrix.target }}
|
||||
JOB_CHANNEL: ${{ matrix.channel }}
|
||||
MAY_SKIP_LIBM_CI: ${{ needs.calculate_vars.outputs.may_skip_libm_ci }}
|
||||
RUN_IN_DOCKER: ${{ matrix.os == 'ubuntu-24.04' }}
|
||||
steps:
|
||||
- name: Print $HOME
|
||||
- name: Print runner information
|
||||
shell: bash
|
||||
run: |
|
||||
set -x
|
||||
echo "${HOME:-not found}"
|
||||
uname -a
|
||||
lscpu || (sysctl -a | grep cpu) || true
|
||||
echo "home: ${HOME:-not found}"
|
||||
pwd
|
||||
printenv
|
||||
- name: Print runner information
|
||||
run: uname -a
|
||||
|
||||
# Native ppc and s390x runners don't have rustup by default
|
||||
- name: Install rustup
|
||||
if: matrix.os == 'ubuntu-24.04-ppc64le' || matrix.os == 'ubuntu-24.04-s390x'
|
||||
run: sudo apt-get update && sudo apt-get install -y rustup
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with: { persist-credentials: false }
|
||||
- name: Install Rust (rustup)
|
||||
shell: bash
|
||||
run: |
|
||||
channel="nightly"
|
||||
# Account for channels that have required components (MinGW)
|
||||
[ -n "${{ matrix.channel }}" ] && channel="${{ matrix.channel }}"
|
||||
[ -n "$JOB_CHANNEL" ] && channel="$JOB_CHANNEL"
|
||||
rustup update "$channel" --no-self-update
|
||||
rustup default "$channel"
|
||||
rustup target add "${{ matrix.target }}"
|
||||
rustup target add "$JOB_TARGET"
|
||||
|
||||
- uses: taiki-e/install-action@nextest
|
||||
- uses: taiki-e/install-action@bfadeaba214680fb4ab63e710bcb2a6a17019fdc # v2.70.4
|
||||
with:
|
||||
tool: nextest@0.9.131
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
|
||||
with:
|
||||
key: ${{ matrix.target }}
|
||||
- name: Cache Docker layers
|
||||
uses: actions/cache@v4
|
||||
if: matrix.os == 'ubuntu-24.04'
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
if: ${{ env.RUN_IN_DOCKER == 'true' }}
|
||||
with:
|
||||
path: /tmp/.buildx-cache
|
||||
key: ${{ matrix.target }}-buildx-${{ github.sha }}
|
||||
restore-keys: ${{ matrix.target }}-buildx-
|
||||
# Configure buildx to use Docker layer caching
|
||||
- uses: docker/setup-buildx-action@v3
|
||||
if: matrix.os == 'ubuntu-24.04'
|
||||
- uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4
|
||||
if: ${{ env.RUN_IN_DOCKER == 'true' }}
|
||||
|
||||
- name: Cache compiler-rt
|
||||
id: cache-compiler-rt
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
with:
|
||||
path: compiler-rt
|
||||
key: ${{ runner.os }}-compiler-rt-${{ hashFiles('ci/download-compiler-rt.sh') }}
|
||||
@@ -166,19 +180,22 @@ jobs:
|
||||
shell: bash
|
||||
|
||||
- name: Verify API list
|
||||
if: matrix.os == 'ubuntu-24.04'
|
||||
run: python3 etc/update-api-list.py --check
|
||||
if: matrix.os == 'ubuntu-24.04' || contains(matrix.os, 'self-hosted')
|
||||
run: |
|
||||
# Must be run on the host (not in Docker) because git and fs access is required.
|
||||
python3 etc/update-api-list.py --check
|
||||
cargo test -p update-api-list
|
||||
|
||||
# Non-linux tests just use our raw script
|
||||
- name: Run locally
|
||||
if: matrix.os != 'ubuntu-24.04'
|
||||
if: ${{ env.RUN_IN_DOCKER != 'true' }}
|
||||
shell: bash
|
||||
run: ./ci/run.sh ${{ matrix.target }}
|
||||
run: ./ci/run.sh "$JOB_TARGET"
|
||||
|
||||
# Otherwise we use our docker containers to run builds
|
||||
- name: Run in Docker
|
||||
if: matrix.os == 'ubuntu-24.04'
|
||||
run: ./ci/run-docker.sh ${{ matrix.target }}
|
||||
if: ${{ env.RUN_IN_DOCKER == 'true' }}
|
||||
run: ./ci/run-docker.sh "$JOB_TARGET"
|
||||
|
||||
- name: Print test logs if available
|
||||
if: always()
|
||||
@@ -189,7 +206,7 @@ jobs:
|
||||
# https://github.com/docker/build-push-action/issues/252
|
||||
# https://github.com/moby/buildkit/issues/1896
|
||||
- name: Move Docker cache
|
||||
if: matrix.os == 'ubuntu-24.04'
|
||||
if: ${{ env.RUN_IN_DOCKER == 'true' }}
|
||||
run: |
|
||||
rm -rf /tmp/.buildx-cache
|
||||
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
|
||||
@@ -199,30 +216,43 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with: { persist-credentials: false }
|
||||
# Unlike rustfmt, stable clippy does not work on code with nightly features.
|
||||
- name: Install nightly `clippy`
|
||||
run: |
|
||||
rustup update nightly --no-self-update
|
||||
rustup default nightly
|
||||
rustup component add clippy
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
|
||||
- name: Download musl source
|
||||
run: ./ci/update-musl.sh
|
||||
- run: cargo clippy --workspace --all-targets
|
||||
|
||||
zizmor:
|
||||
name: Zizmor (Static analysis for GitHub Actions)
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
security-events: write
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with: { persist-credentials: false }
|
||||
- uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2
|
||||
|
||||
build-custom:
|
||||
name: Build custom target
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with: { persist-credentials: false }
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup update nightly --no-self-update
|
||||
rustup default nightly
|
||||
rustup component add rust-src
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
|
||||
- run: |
|
||||
# Ensure we can build with custom target.json files (these can interact
|
||||
# poorly with build scripts)
|
||||
@@ -237,13 +267,14 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with: { persist-credentials: false }
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup update nightly --no-self-update
|
||||
rustup default nightly
|
||||
rustup component add rust-src
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
|
||||
- run: |
|
||||
cargo build -p compiler_builtins -p libm \
|
||||
--target etc/thumbv6-none-eabi.json \
|
||||
@@ -252,23 +283,30 @@ jobs:
|
||||
|
||||
benchmarks:
|
||||
name: Benchmarks
|
||||
timeout-minutes: 20
|
||||
timeout-minutes: 30
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- target: x86_64-unknown-linux-gnu
|
||||
os: ubuntu-24.04
|
||||
- target: aarch64-unknown-linux-gnu
|
||||
os: ubuntu-24.04-arm
|
||||
- target: i686-unknown-linux-gnu
|
||||
os: ubuntu-24.04
|
||||
- target: x86_64-unknown-linux-gnu
|
||||
os: ubuntu-24.04
|
||||
runs-on: ${{ matrix.os }}
|
||||
env:
|
||||
JOB_TARGET: ${{ matrix.target }}
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: taiki-e/install-action@cargo-binstall
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with: { persist-credentials: false }
|
||||
- uses: taiki-e/install-action@bfadeaba214680fb4ab63e710bcb2a6a17019fdc # v2.70.4
|
||||
with:
|
||||
tool: cargo-binstall@1.17.7
|
||||
|
||||
- name: Set up dependencies
|
||||
run: ./ci/install-bench-deps.sh
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
run: ./ci/install-bench-deps.sh "$JOB_TARGET"
|
||||
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
|
||||
with:
|
||||
key: ${{ matrix.target }}
|
||||
- name: Download musl source
|
||||
@@ -278,17 +316,14 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
PR_NUMBER: ${{ github.event.pull_request.number }}
|
||||
run: ./ci/bench-icount.sh ${{ matrix.target }}
|
||||
run: ./ci/bench-icount.sh "$JOB_TARGET"
|
||||
|
||||
- name: Upload the benchmark baseline
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: ${{ env.BASELINE_NAME }}
|
||||
path: ${{ env.BASELINE_NAME }}.tar.xz
|
||||
|
||||
- name: Run wall time benchmarks
|
||||
run: ./ci/bench-walltime.sh
|
||||
|
||||
- name: Print test logs if available
|
||||
if: always()
|
||||
run: if [ -f "target/test-log.txt" ]; then cat target/test-log.txt; fi
|
||||
@@ -299,15 +334,14 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with: { persist-credentials: false }
|
||||
- name: Install Rust (rustup)
|
||||
# FIXME(ci): not working in the 2026-02-11 nightly
|
||||
# https://rust-lang.zulipchat.com/#narrow/channel/269128-miri/topic/build-script-build.20contains.20outdated.20or.20invalid.20JSON/with/573426109
|
||||
run: rustup update nightly-2026-02-10 --no-self-update && rustup default nightly-2026-02-10
|
||||
run: rustup update nightly --no-self-update && rustup default nightly
|
||||
shell: bash
|
||||
- run: rustup component add miri
|
||||
- run: cargo miri setup
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
|
||||
- run: ./ci/miri.sh
|
||||
|
||||
msrv:
|
||||
@@ -317,13 +351,14 @@ jobs:
|
||||
env:
|
||||
RUSTFLAGS: # No need to check warnings on old MSRV, unset `-Dwarnings`
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with: { persist-credentials: false }
|
||||
- name: Install Rust
|
||||
run: |
|
||||
msrv="$(perl -ne 'print if s/rust-version\s*=\s*"(.*)"/\1/g' libm/Cargo.toml)"
|
||||
echo "MSRV: $msrv"
|
||||
rustup update "$msrv" --no-self-update && rustup default "$msrv"
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
|
||||
- run: |
|
||||
# FIXME(msrv): Remove the workspace Cargo.toml so 1.63 cargo doesn't see
|
||||
# `edition = "2024"` and get spooked.
|
||||
@@ -335,7 +370,8 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with: { persist-credentials: false }
|
||||
- name: Install nightly `rustfmt`
|
||||
run: rustup set profile minimal && rustup default nightly && rustup component add rustfmt
|
||||
- run: cargo fmt -- --check
|
||||
@@ -358,12 +394,13 @@ jobs:
|
||||
env:
|
||||
TO_TEST: ${{ matrix.to_test }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with: { persist-credentials: false }
|
||||
- name: Install Rust
|
||||
run: |
|
||||
rustup update nightly --no-self-update
|
||||
rustup default nightly
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- uses: Swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2.9.1
|
||||
- name: download musl source
|
||||
run: ./ci/update-musl.sh
|
||||
- name: Run extensive tests
|
||||
@@ -383,13 +420,16 @@ jobs:
|
||||
- msrv
|
||||
- rustfmt
|
||||
- test
|
||||
- zizmor
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 10
|
||||
# GitHub branch protection is exceedingly silly and treats "jobs skipped because a dependency
|
||||
# failed" as success. So we have to do some contortions to ensure the job fails if any of its
|
||||
# dependencies fails.
|
||||
if: always() # make sure this is never "skipped"
|
||||
env:
|
||||
NEEDS: ${{ toJson(needs) }}
|
||||
steps:
|
||||
# Manually check the status of all dependencies. `if: failure()` does not work.
|
||||
- name: check if any dependency failed
|
||||
run: jq --exit-status 'all(.result == "success")' <<< '${{ toJson(needs) }}'
|
||||
run: jq --exit-status 'all(.result == "success")' <<< "$NEEDS"
|
||||
|
||||
@@ -11,15 +11,15 @@ jobs:
|
||||
release-plz:
|
||||
name: Release-plz
|
||||
runs-on: ubuntu-24.04
|
||||
environment: publish
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
fetch-depth: 0
|
||||
- name: Install Rust (rustup)
|
||||
run: rustup update nightly --no-self-update && rustup default nightly
|
||||
- name: Run release-plz
|
||||
uses: MarcoIeni/release-plz-action@v0.5
|
||||
uses: release-plz/action@1528104d2ca23787631a1c1f022abb64b34c1e11 # v0.5
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
||||
|
||||
@@ -5,7 +5,7 @@ on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
# Run at 04:00 UTC every Monday and Thursday
|
||||
- cron: '0 4 * * 1,4'
|
||||
- cron: "0 4 * * 1,4"
|
||||
|
||||
env:
|
||||
JOSH_SYNC_VERBOSE: true
|
||||
@@ -13,15 +13,19 @@ env:
|
||||
jobs:
|
||||
pull:
|
||||
if: github.repository == 'rust-lang/compiler-builtins'
|
||||
uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main
|
||||
uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@8970a6eb3a6095db68e4d765b3b5fba5e9c42cf6 # main
|
||||
with:
|
||||
github-app-id: ${{ vars.APP_CLIENT_ID }}
|
||||
pr-author: "workflows-compiler-builtins[bot]"
|
||||
# https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/compiler-builtins.20subtree.20sync.20automation/with/528482375
|
||||
zulip-stream-id: 219381
|
||||
zulip-topic: 'compiler-builtins subtree sync automation'
|
||||
zulip-topic: "compiler-builtins subtree sync automation"
|
||||
zulip-bot-email: "compiler-builtins-ci-bot@rust-lang.zulipchat.com"
|
||||
pr-base-branch: main
|
||||
branch-name: rustc-pull
|
||||
secrets:
|
||||
zulip-api-token: ${{ secrets.ZULIP_API_TOKEN }}
|
||||
github-app-secret: ${{ secrets.APP_PRIVATE_KEY }}
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
|
||||
@@ -34,9 +34,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.21"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
|
||||
checksum = "824a212faf96e9acacdbd09febd34438f8f711fb84e09a8916013cd7815ca28d"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
@@ -49,15 +49,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.13"
|
||||
version = "1.0.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
|
||||
checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.7"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
|
||||
checksum = "52ce7f38b242319f7cabaa6813055467063ecdc9d355bbb4ce0c68908cd8130e"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
@@ -68,7 +68,7 @@ version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -79,20 +79,24 @@ checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.101"
|
||||
version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea"
|
||||
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||
|
||||
[[package]]
|
||||
name = "api-list-common"
|
||||
version = "0.1.0"
|
||||
|
||||
[[package]]
|
||||
name = "assert_cmd"
|
||||
version = "2.1.2"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c5bcfa8749ac45dd12cb11055aeeb6b27a3895560d60d71e3c23bf979e60514"
|
||||
checksum = "9a686bbee5efb88a82df0621b236e74d925f470e5445d3220a5648b892ec99c9"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"bstr",
|
||||
@@ -151,16 +155,13 @@ dependencies = [
|
||||
"paste",
|
||||
"rand_xoshiro",
|
||||
"rustc_apfloat",
|
||||
"test",
|
||||
"utest-cortex-m-qemu",
|
||||
"utest-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.19.1"
|
||||
version = "3.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
|
||||
checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
@@ -170,9 +171,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.56"
|
||||
version = "1.2.58"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2"
|
||||
checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"shlex",
|
||||
@@ -224,9 +225,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.58"
|
||||
version = "4.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63be97961acde393029492ce0be7a1af7e323e6bae9511ebfac33751be5e6806"
|
||||
checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
@@ -234,9 +235,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.58"
|
||||
version = "4.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f13174bda5dfd69d7e947827e5af4b0f2f94a4a3ee92912fba07a66150f21e2"
|
||||
checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -246,9 +247,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.55"
|
||||
version = "4.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5"
|
||||
checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
@@ -258,15 +259,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "1.0.0"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
||||
checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.4"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||
checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570"
|
||||
|
||||
[[package]]
|
||||
name = "compiler_builtins"
|
||||
@@ -277,14 +278,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "console"
|
||||
version = "0.16.2"
|
||||
version = "0.16.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03e45a4a8926227e4197636ba97a9fc9b00477e9f4bd711395687c5f0734bec4"
|
||||
checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87"
|
||||
dependencies = [
|
||||
"encode_unicode",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -391,6 +391,12 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||
|
||||
[[package]]
|
||||
name = "difflib"
|
||||
version = "0.4.0"
|
||||
@@ -422,7 +428,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -470,9 +476,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.4.1"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
|
||||
checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
@@ -485,20 +491,26 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gmp-mpfr-sys"
|
||||
version = "1.6.8"
|
||||
name = "glob"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60f8970a75c006bb2f8ae79c6768a116dd215fa8346a87aed99bf9d82ca43394"
|
||||
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
||||
|
||||
[[package]]
|
||||
name = "gmp-mpfr-sys"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8cfc928d8ff4ab3767a3674cf55f81186436fb6070866bb1443ffe65a640d2d6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gungraun"
|
||||
version = "0.17.2"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61c1bbe46f51c63bc08a1fac0ee0c530a77c961613a86ecf828ab1b0ffc6687a"
|
||||
checksum = "2e2e7d17b75a18300d495a5e79970067b92d74e4858c28326e125f2d55b1b566"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"derive_more",
|
||||
@@ -508,9 +520,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gungraun-macros"
|
||||
version = "0.7.2"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cdccd089c36fb2ee66ef0eb7b1baa3ce7e7878a8eae682d9c8c368869ff6eca1"
|
||||
checksum = "e35c7fb6133421db1cf752b7a2838d9277a26810ccaeeca7aa449f96ad7c2b01"
|
||||
dependencies = [
|
||||
"derive_more",
|
||||
"proc-macro-error2",
|
||||
@@ -524,9 +536,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "gungraun-runner"
|
||||
version = "0.17.2"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6da6487203fa53ae6b1c8fead642fe79a3199464b0dd1337635594d675a9ac05"
|
||||
checksum = "c19bb4c552085f983300b11694022d7584810dca3500c220962ab2353327fb45"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -610,15 +622,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.17"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
||||
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.85"
|
||||
version = "0.3.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3"
|
||||
checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"wasm-bindgen",
|
||||
@@ -632,9 +644,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.182"
|
||||
version = "0.2.183"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
|
||||
checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d"
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
@@ -653,6 +665,7 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981"
|
||||
name = "libm-macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"api-list-common",
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -664,6 +677,8 @@ name = "libm-test"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"api-list-common",
|
||||
"compiler_builtins",
|
||||
"criterion",
|
||||
"getrandom",
|
||||
"gmp-mpfr-sys",
|
||||
@@ -682,9 +697,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libtest-mimic"
|
||||
version = "0.8.1"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5297962ef19edda4ce33aaa484386e0a5b3d7f2f4e037cbeee00503ef6b29d33"
|
||||
checksum = "14e6ba06f0ade6e504aff834d7c34298e5155c6baca353cc6a4aaff2f9fd7f33"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
@@ -694,9 +709,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.11.0"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
|
||||
checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
@@ -750,21 +765,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.38.1"
|
||||
version = "0.39.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271638cd5fa9cca89c4c304675ca658efc4e64a66c716b7cfe1afb4b9611dbbc"
|
||||
checksum = "63944c133d03f44e75866bbd160b95af0ec3f6a13d936d69d31c81078cbc5baf"
|
||||
dependencies = [
|
||||
"flate2",
|
||||
"memchr",
|
||||
"ruzstd",
|
||||
"wasmparser 0.243.0",
|
||||
"wasmparser 0.245.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
version = "1.21.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell_polyfill"
|
||||
@@ -868,6 +883,16 @@ dependencies = [
|
||||
"termtree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
|
||||
dependencies = [
|
||||
"diff",
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.37"
|
||||
@@ -911,24 +936,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.44"
|
||||
version = "1.0.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
|
||||
checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.10.0"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8"
|
||||
checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207"
|
||||
dependencies = [
|
||||
"chacha20",
|
||||
"getrandom",
|
||||
@@ -1005,15 +1030,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.9"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c"
|
||||
checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a"
|
||||
|
||||
[[package]]
|
||||
name = "rug"
|
||||
version = "1.28.1"
|
||||
version = "1.29.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de190ec858987c79cad4da30e19e546139b3339331282832af004d0ea7829639"
|
||||
checksum = "25f6c8f906c90b48e0c1745c9f814c3a31c5eba847043b05c3e9a934dec7c4b3"
|
||||
dependencies = [
|
||||
"az",
|
||||
"gmp-mpfr-sys",
|
||||
@@ -1042,15 +1067,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.1.3"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34"
|
||||
checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1077,12 +1102,6 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sc"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "010e18bd3bfd1d45a7e666b236c78720df0d9a7698ebaa9c1c559961eb60a38b"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.27"
|
||||
@@ -1140,9 +1159,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.8"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2"
|
||||
checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
@@ -1171,9 +1190,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.116"
|
||||
version = "2.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3df424c70518695237746f84cede799c9c58fcb37450d7b23716568cc8bc69cb"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -1182,15 +1201,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.25.0"
|
||||
version = "3.27.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1"
|
||||
checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1199,11 +1218,6 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
|
||||
|
||||
[[package]]
|
||||
name = "test"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/japaric/utest#e32073e2b078e3bee46001c13ae4c1acf368d762"
|
||||
|
||||
[[package]]
|
||||
name = "tinytemplate"
|
||||
version = "1.2.1"
|
||||
@@ -1245,18 +1259,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3"
|
||||
|
||||
[[package]]
|
||||
name = "utest-cortex-m-qemu"
|
||||
name = "update-api-list"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/japaric/utest#e32073e2b078e3bee46001c13ae4c1acf368d762"
|
||||
dependencies = [
|
||||
"sc",
|
||||
"api-list-common",
|
||||
"getopts",
|
||||
"glob",
|
||||
"pretty_assertions",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "utest-macros"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/japaric/utest#e32073e2b078e3bee46001c13ae4c1acf368d762"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
@@ -1314,9 +1326,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.108"
|
||||
version = "0.2.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566"
|
||||
checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
@@ -1327,9 +1339,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.108"
|
||||
version = "0.2.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608"
|
||||
checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -1337,9 +1349,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.108"
|
||||
version = "0.2.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55"
|
||||
checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"proc-macro2",
|
||||
@@ -1350,9 +1362,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.108"
|
||||
version = "0.2.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12"
|
||||
checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
@@ -1379,15 +1391,6 @@ dependencies = [
|
||||
"wasmparser 0.244.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.243.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6d8db401b0528ec316dfbe579e6ab4152d61739cfe076706d2009127970159d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmparser"
|
||||
version = "0.244.0"
|
||||
@@ -1401,10 +1404,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.85"
|
||||
name = "wasmparser"
|
||||
version = "0.245.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598"
|
||||
checksum = "4f08c9adee0428b7bddf3890fc27e015ac4b761cc608c822667102b8bfd6995e"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
@@ -1442,7 +1454,7 @@ version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1457,15 +1469,6 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
@@ -1475,71 +1478,6 @@ dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen"
|
||||
version = "0.51.0"
|
||||
@@ -1629,19 +1567,25 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.39"
|
||||
name = "yansi"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a"
|
||||
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.39"
|
||||
version = "0.8.48"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517"
|
||||
checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
||||
@@ -3,10 +3,12 @@ resolver = "2"
|
||||
members = [
|
||||
"builtins-shim",
|
||||
"builtins-test",
|
||||
"crates/api-list-common",
|
||||
"crates/libm-macros",
|
||||
"crates/musl-math-sys",
|
||||
"crates/panic-handler",
|
||||
"crates/symbol-check",
|
||||
"crates/update-api-list",
|
||||
"crates/util",
|
||||
"libm",
|
||||
"libm-test",
|
||||
@@ -15,14 +17,15 @@ members = [
|
||||
default-members = [
|
||||
"builtins-shim",
|
||||
"builtins-test",
|
||||
"crates/api-list-common",
|
||||
"crates/libm-macros",
|
||||
"libm",
|
||||
"libm-test",
|
||||
]
|
||||
|
||||
exclude = [
|
||||
# `builtins-test-intrinsics` needs the feature `compiler-builtins` enabled
|
||||
# and `mangled-names` disabled, which is the opposite of what is needed for
|
||||
# `builtins-test-intrinsics` needs the features `compiler-builtins` and
|
||||
# `unmangled-names` enabled, which is the opposite of what is needed for
|
||||
# other tests, so it makes sense to keep it out of the workspace.
|
||||
"builtins-test-intrinsics",
|
||||
# We test via the `builtins-shim` crate, so exclude the `compiler-builtins`
|
||||
@@ -33,6 +36,7 @@ exclude = [
|
||||
|
||||
[workspace.dependencies]
|
||||
anyhow = "1.0.101"
|
||||
api-list-common = { path = "crates/api-list-common" }
|
||||
assert_cmd = "2.1.2"
|
||||
cc = "1.2.56"
|
||||
cfg-if = "1.0.4"
|
||||
@@ -40,8 +44,9 @@ compiler_builtins = { path = "builtins-shim", default-features = false }
|
||||
criterion = { version = "0.8.2", default-features = false, features = ["cargo_bench_support"] }
|
||||
getopts = "0.2.24"
|
||||
getrandom = "0.4.1"
|
||||
glob = "0.3.3"
|
||||
gmp-mpfr-sys = { version = "1.6.8", default-features = false }
|
||||
gungraun = "0.17.2"
|
||||
gungraun = "0.18.0"
|
||||
heck = "0.5.0"
|
||||
indicatif = { version = "0.18.3", default-features = false }
|
||||
libm = { path = "libm", default-features = false }
|
||||
@@ -50,9 +55,10 @@ libm-test = { path = "libm-test", default-features = false }
|
||||
libtest-mimic = "0.8.1"
|
||||
musl-math-sys = { path = "crates/musl-math-sys" }
|
||||
no-panic = "0.1.36"
|
||||
object = { version = "0.38.1", features = ["wasm"] }
|
||||
object = { version = "0.39.0", features = ["wasm"] }
|
||||
panic-handler = { path = "crates/panic-handler" }
|
||||
paste = "1.0.15"
|
||||
pretty_assertions = "1.4.1"
|
||||
proc-macro2 = "1.0.106"
|
||||
quote = "1.0.44"
|
||||
rand = "0.10.0"
|
||||
|
||||
@@ -39,27 +39,28 @@ test = false
|
||||
cc = { version = "1.2", optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
default = ["arch"]
|
||||
|
||||
# Enable architecture-specific features such as SIMD or assembly routines. If
|
||||
# disabled, the generic version can be tested on any platform.
|
||||
arch = []
|
||||
|
||||
# Enable compilation of C code in compiler-rt, filling in some more optimized
|
||||
# implementations and also filling in unimplemented intrinsics
|
||||
c = ["dep:cc"]
|
||||
|
||||
# For implementations where there is both a generic version and a platform-
|
||||
# specific version, use the generic version. This is meant to enable testing
|
||||
# the generic versions on all platforms.
|
||||
no-asm = []
|
||||
|
||||
# Flag this library as the unstable compiler-builtins lib. This must be enabled
|
||||
# when using as `std`'s dependency.'
|
||||
compiler-builtins = []
|
||||
compiler-builtins = ["unmangled-names"]
|
||||
|
||||
# Generate memory-related intrinsics like memcpy
|
||||
# Enable `no_mangle` symbols for memory-related intrinsics like memcpy. The
|
||||
# mangled versions are always available.
|
||||
mem = []
|
||||
|
||||
# Mangle all names so this can be linked in with other versions or other
|
||||
# compiler-rt implementations. Also used for testing
|
||||
mangled-names = []
|
||||
# Enable `no_mangle` symbols so this crate gets used as the runtime intrinsic
|
||||
# implementation. Leave this disabled for testing to avoid conflicting with
|
||||
# the system intrinsics.
|
||||
unmangled-names = []
|
||||
|
||||
# This makes certain traits and function specializations public that
|
||||
# are not normally public but are required by the `builtins-test`
|
||||
|
||||
@@ -6,9 +6,15 @@ publish = false
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
||||
[dependencies]
|
||||
compiler_builtins = { path = "../builtins-shim", features = ["compiler-builtins"] }
|
||||
# FIXME: `aeabi_mem*` tests will require the "mem" feature to be enabled here.
|
||||
compiler_builtins = { path = "../builtins-shim", features = ["compiler-builtins", "unmangled-names"] }
|
||||
panic-handler = { path = "../crates/panic-handler" }
|
||||
|
||||
[target.'cfg(all(target_arch = "arm", not(any(target_env = "gnu", target_env = "musl")), target_os = "linux"))'.dev-dependencies]
|
||||
test = { git = "https://github.com/japaric/utest" }
|
||||
utest-cortex-m-qemu = { default-features = false, git = "https://github.com/japaric/utest" }
|
||||
utest-macros = { git = "https://github.com/japaric/utest" }
|
||||
|
||||
[features]
|
||||
c = ["compiler_builtins/c"]
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
mod builtins_configure {
|
||||
include!("../compiler-builtins/configure.rs");
|
||||
}
|
||||
#[path = "../libm/configure.rs"]
|
||||
mod configure;
|
||||
|
||||
use configure::{Config, Library};
|
||||
|
||||
fn main() {
|
||||
println!("cargo::rerun-if-changed=../configure.rs");
|
||||
|
||||
let target = builtins_configure::Target::from_env();
|
||||
builtins_configure::configure_aliases(&target);
|
||||
println!("cargo::rerun-if-changed=../libm/configure.rs");
|
||||
let cfg = Config::from_env(Library::BuiltinsTestIntrinsics);
|
||||
configure::emit(&cfg);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
// By compiling this file we check that all the intrinsics we care about continue to be provided by
|
||||
// the `compiler_builtins` crate regardless of the changes we make to it. If we, by mistake, stop
|
||||
// compiling a C implementation and forget to implement that intrinsic in Rust, this file will fail
|
||||
// to link due to the missing intrinsic (symbol).
|
||||
//! Tests that require unmangled symbols from `compiler-builtins`.
|
||||
//!
|
||||
//! By compiling this file we check that all the intrinsics we care about continue to be provided by
|
||||
//! the `compiler_builtins` crate regardless of the changes we make to it. If we, by mistake, stop
|
||||
//! compiling a C implementation and forget to implement that intrinsic in Rust, this file will fail
|
||||
//! to link due to the missing intrinsic (symbol).
|
||||
|
||||
#![allow(internal_features, unused_features)]
|
||||
#![deny(dead_code)]
|
||||
|
||||
-1
@@ -2,7 +2,6 @@
|
||||
target_arch = "arm",
|
||||
not(any(target_env = "gnu", target_env = "musl")),
|
||||
target_os = "linux",
|
||||
feature = "mem"
|
||||
))]
|
||||
#![feature(compiler_builtins_lib)]
|
||||
#![no_std]
|
||||
-1
@@ -2,7 +2,6 @@
|
||||
target_arch = "arm",
|
||||
not(any(target_env = "gnu", target_env = "musl")),
|
||||
target_os = "linux",
|
||||
feature = "mem"
|
||||
))]
|
||||
#![feature(compiler_builtins_lib)]
|
||||
#![no_std]
|
||||
-1
@@ -2,7 +2,6 @@
|
||||
target_arch = "arm",
|
||||
not(any(target_env = "gnu", target_env = "musl")),
|
||||
target_os = "linux",
|
||||
feature = "mem"
|
||||
))]
|
||||
#![feature(compiler_builtins_lib)]
|
||||
#![no_std]
|
||||
@@ -6,7 +6,7 @@ publish = false
|
||||
license = "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)"
|
||||
|
||||
[dependencies]
|
||||
compiler_builtins = { workspace = true, features = ["unstable-public-internals"] }
|
||||
compiler_builtins = { workspace = true, default-features = false, features = ["unstable-public-internals"] }
|
||||
|
||||
# For fuzzing tests we want a deterministic seedable RNG. We also eliminate potential
|
||||
# problems with system RNGs on the variety of platforms this crate is tested on.
|
||||
@@ -23,25 +23,11 @@ gungraun = { workspace = true, optional = true }
|
||||
[dev-dependencies]
|
||||
paste.workspace = true
|
||||
|
||||
[target.'cfg(all(target_arch = "arm", not(any(target_env = "gnu", target_env = "musl")), target_os = "linux"))'.dev-dependencies]
|
||||
test = { git = "https://github.com/japaric/utest" }
|
||||
utest-cortex-m-qemu = { default-features = false, git = "https://github.com/japaric/utest" }
|
||||
utest-macros = { git = "https://github.com/japaric/utest" }
|
||||
|
||||
[features]
|
||||
default = ["mangled-names"]
|
||||
# Defaults should match the defaults in compiler-builtins since we have that
|
||||
# dependency with `default-features=false`.
|
||||
default = ["compiler_builtins/arch"]
|
||||
c = ["compiler_builtins/c"]
|
||||
no-asm = ["compiler_builtins/no-asm"]
|
||||
mem = ["compiler_builtins/mem"]
|
||||
mangled-names = ["compiler_builtins/mangled-names"]
|
||||
# Skip tests that rely on f128 symbols being available on the system
|
||||
no-sys-f128 = ["no-sys-f128-int-convert", "no-sys-f16-f128-convert"]
|
||||
# Some platforms have some f128 functions but everything except integer conversions
|
||||
no-sys-f128-int-convert = []
|
||||
no-sys-f16-f128-convert = []
|
||||
no-sys-f16-f64-convert = []
|
||||
# Skip tests that rely on f16 symbols being available on the system
|
||||
no-sys-f16 = ["no-sys-f16-f64-convert"]
|
||||
|
||||
# Enable icount benchmarks (requires gungraun-runner and valgrind locally)
|
||||
icount = ["dep:gungraun"]
|
||||
@@ -51,11 +37,6 @@ icount = ["dep:gungraun"]
|
||||
benchmarking-reports = ["walltime", "criterion/plotters", "criterion/html_reports"]
|
||||
walltime = ["dep:criterion"]
|
||||
|
||||
# NOTE: benchmarks must be run with `--no-default-features` or with
|
||||
# `-p builtins-test`, otherwise the default `compiler-builtins` feature
|
||||
# of the `compiler_builtins` crate gets activated, resulting in linker
|
||||
# errors.
|
||||
|
||||
[[bench]]
|
||||
name = "float_add"
|
||||
harness = false
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
crate_fn_ppc: add::__addkf3,
|
||||
sys_fn: __addtf3,
|
||||
sys_fn_ppc: __addkf3,
|
||||
sys_available: not(feature = "no-sys-f128"),
|
||||
sys_available: not(no_sys_f128),
|
||||
asm: []
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ fn gt_res_eq(mut a: CmpResult, mut b: CmpResult) -> bool {
|
||||
crate_fn_ppc: cmp::__gtkf2,
|
||||
sys_fn: __gttf2,
|
||||
sys_fn_ppc: __gtkf2,
|
||||
sys_available: not(feature = "no-sys-f128"),
|
||||
sys_available: not(no_sys_f128),
|
||||
output_eq: gt_res_eq,
|
||||
asm: []
|
||||
}
|
||||
@@ -198,7 +198,7 @@ fn gt_res_eq(mut a: CmpResult, mut b: CmpResult) -> bool {
|
||||
crate_fn_ppc: cmp::__unordkf2,
|
||||
sys_fn: __unordtf2,
|
||||
sys_fn_ppc: __unordkf2,
|
||||
sys_available: not(feature = "no-sys-f128"),
|
||||
sys_available: not(no_sys_f128),
|
||||
asm: []
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
crate_fn_ppc: conv::__floatunsikf,
|
||||
sys_fn: __floatunsitf,
|
||||
sys_fn_ppc: __floatunsikf,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: []
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
crate_fn_ppc: conv::__floatundikf,
|
||||
sys_fn: __floatunditf,
|
||||
sys_fn_ppc: __floatundikf,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: []
|
||||
}
|
||||
|
||||
@@ -168,7 +168,7 @@
|
||||
crate_fn_ppc: conv::__floatuntikf,
|
||||
sys_fn: __floatuntitf,
|
||||
sys_fn_ppc: __floatuntikf,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: []
|
||||
}
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
crate_fn_ppc: conv::__floatsikf,
|
||||
sys_fn: __floatsitf,
|
||||
sys_fn_ppc: __floatsikf,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: []
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@
|
||||
crate_fn_ppc: conv::__floatdikf,
|
||||
sys_fn: __floatditf,
|
||||
sys_fn_ppc: __floatdikf,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: []
|
||||
}
|
||||
|
||||
@@ -358,7 +358,7 @@
|
||||
crate_fn_ppc: conv::__floattikf,
|
||||
sys_fn: __floattitf,
|
||||
sys_fn_ppc: __floattikf,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: []
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@
|
||||
crate_fn: conv::__fixunstfsi,
|
||||
crate_fn_ppc: conv::__fixunskfsi,
|
||||
sys_fn: __fixunstfsi,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: []
|
||||
}
|
||||
|
||||
@@ -484,7 +484,7 @@
|
||||
crate_fn: conv::__fixunstfdi,
|
||||
crate_fn_ppc: conv::__fixunskfdi,
|
||||
sys_fn: __fixunstfdi,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: []
|
||||
}
|
||||
|
||||
@@ -495,7 +495,7 @@
|
||||
crate_fn: conv::__fixunstfti,
|
||||
crate_fn_ppc: conv::__fixunskfti,
|
||||
sys_fn: __fixunstfti,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: []
|
||||
}
|
||||
|
||||
@@ -610,7 +610,7 @@
|
||||
crate_fn: conv::__fixtfsi,
|
||||
crate_fn_ppc: conv::__fixkfsi,
|
||||
sys_fn: __fixtfsi,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: []
|
||||
}
|
||||
|
||||
@@ -621,7 +621,7 @@
|
||||
crate_fn: conv::__fixtfdi,
|
||||
crate_fn_ppc: conv::__fixkfdi,
|
||||
sys_fn: __fixtfdi,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: []
|
||||
}
|
||||
|
||||
@@ -632,7 +632,7 @@
|
||||
crate_fn: conv::__fixtfti,
|
||||
crate_fn_ppc: conv::__fixkfti,
|
||||
sys_fn: __fixtfti,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: []
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
crate_fn_ppc: div::__divkf3,
|
||||
sys_fn: __divtf3,
|
||||
sys_fn_ppc: __divkf3,
|
||||
sys_available: not(feature = "no-sys-f128"),
|
||||
sys_available: not(no_sys_f128),
|
||||
asm: []
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
sig: (a: f16) -> f32,
|
||||
crate_fn: extend::__extendhfsf2,
|
||||
sys_fn: __extendhfsf2,
|
||||
sys_available: not(feature = "no-sys-f16"),
|
||||
sys_available: not(no_sys_f16),
|
||||
asm: [
|
||||
#[cfg(target_arch = "aarch64")] {
|
||||
let ret: f32;
|
||||
@@ -34,7 +34,7 @@
|
||||
sig: (a: f16) -> f64,
|
||||
crate_fn: extend::__extendhfdf2,
|
||||
sys_fn: __extendhfdf2,
|
||||
sys_available: not(feature = "no-sys-f16-f64-convert"),
|
||||
sys_available: not(no_sys_f16_f64_convert),
|
||||
asm: [
|
||||
#[cfg(target_arch = "aarch64")] {
|
||||
let ret: f64;
|
||||
@@ -58,7 +58,7 @@
|
||||
crate_fn_ppc: extend::__extendhfkf2,
|
||||
sys_fn: __extendhftf2,
|
||||
sys_fn_ppc: __extendhfkf2,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: [],
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
crate_fn_ppc: extend::__extendsfkf2,
|
||||
sys_fn: __extendsftf2,
|
||||
sys_fn_ppc: __extendsfkf2,
|
||||
sys_available: not(feature = "no-sys-f128"),
|
||||
sys_available: not(no_sys_f128),
|
||||
asm: [],
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@
|
||||
crate_fn_ppc: extend::__extenddfkf2,
|
||||
sys_fn: __extenddftf2,
|
||||
sys_fn_ppc: __extenddfkf2,
|
||||
sys_available: not(feature = "no-sys-f128"),
|
||||
sys_available: not(no_sys_f128),
|
||||
asm: [],
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
crate_fn_ppc: mul::__mulkf3,
|
||||
sys_fn: __multf3,
|
||||
sys_fn_ppc: __mulkf3,
|
||||
sys_available: not(feature = "no-sys-f128"),
|
||||
sys_available: not(no_sys_f128),
|
||||
asm: []
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
// FIXME(f16_f128): can be changed to only `f128_enabled` once `__multf3` and `__divtf3` are
|
||||
// distributed by nightly.
|
||||
#[cfg(all(f128_enabled, not(feature = "no-sys-f128")))]
|
||||
#[cfg(all(f128_enabled, not(no_sys_f128)))]
|
||||
float_bench! {
|
||||
name: powi_f128,
|
||||
sig: (a: f128, b: i32) -> f128,
|
||||
@@ -32,7 +32,7 @@
|
||||
crate_fn_ppc: pow::__powikf2,
|
||||
sys_fn: __powitf2,
|
||||
sys_fn_ppc: __powikf2,
|
||||
sys_available: not(feature = "no-sys-f128"),
|
||||
sys_available: not(no_sys_f128),
|
||||
asm: []
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ pub fn float_pow() {
|
||||
powi_f32(&mut criterion);
|
||||
powi_f64(&mut criterion);
|
||||
|
||||
#[cfg(all(f128_enabled, not(feature = "no-sys-f128")))]
|
||||
#[cfg(all(f128_enabled, not(no_sys_f128)))]
|
||||
powi_f128(&mut criterion);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
crate_fn_ppc: sub::__subkf3,
|
||||
sys_fn: __subtf3,
|
||||
sys_fn_ppc: __subkf3,
|
||||
sys_available: not(feature = "no-sys-f128"),
|
||||
sys_available: not(no_sys_f128),
|
||||
asm: []
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
sig: (a: f32) -> f16,
|
||||
crate_fn: trunc::__truncsfhf2,
|
||||
sys_fn: __truncsfhf2,
|
||||
sys_available: not(feature = "no-sys-f16"),
|
||||
sys_available: not(no_sys_f16),
|
||||
asm: [
|
||||
#[cfg(target_arch = "aarch64")] {
|
||||
let ret: f16;
|
||||
@@ -33,7 +33,7 @@
|
||||
sig: (a: f64) -> f16,
|
||||
crate_fn: trunc::__truncdfhf2,
|
||||
sys_fn: __truncdfhf2,
|
||||
sys_available: not(feature = "no-sys-f16-f64-convert"),
|
||||
sys_available: not(no_sys_f16_f64_convert),
|
||||
asm: [
|
||||
#[cfg(target_arch = "aarch64")] {
|
||||
let ret: f16;
|
||||
@@ -90,7 +90,7 @@
|
||||
crate_fn_ppc: trunc::__trunckfhf2,
|
||||
sys_fn: __trunctfhf2,
|
||||
sys_fn_ppc: __trunckfhf2,
|
||||
sys_available: not(feature = "no-sys-f16-f128-convert"),
|
||||
sys_available: not(no_sys_f16_f128_convert),
|
||||
asm: [],
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
crate_fn_ppc: trunc::__trunckfsf2,
|
||||
sys_fn: __trunctfsf2,
|
||||
sys_fn_ppc: __trunckfsf2,
|
||||
sys_available: not(feature = "no-sys-f128"),
|
||||
sys_available: not(no_sys_f128),
|
||||
asm: [],
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
crate_fn_ppc: trunc::__trunckfdf2,
|
||||
sys_fn: __trunctfdf2,
|
||||
sys_fn_ppc: __trunckfdf2,
|
||||
sys_available: not(feature = "no-sys-f128"),
|
||||
sys_available: not(no_sys_f128),
|
||||
asm: [],
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ fn bench_cpy((len, mut dst, src): (usize, AlignedSlice, AlignedSlice)) {
|
||||
}
|
||||
}
|
||||
|
||||
library_benchmark_group!(name = memcpy; benchmarks = bench_cpy);
|
||||
library_benchmark_group!(name = memcpy, benchmarks = [bench_cpy]);
|
||||
}
|
||||
|
||||
mod mset {
|
||||
@@ -167,7 +167,7 @@ fn bench_set((len, mut dst): (usize, AlignedSlice)) {
|
||||
}
|
||||
}
|
||||
|
||||
library_benchmark_group!(name = memset; benchmarks = bench_set);
|
||||
library_benchmark_group!(name = memset, benchmarks = [bench_set]);
|
||||
}
|
||||
|
||||
mod mcmp {
|
||||
@@ -235,7 +235,7 @@ fn bench_cmp((len, mut dst, src): (usize, AlignedSlice, AlignedSlice)) {
|
||||
}
|
||||
}
|
||||
|
||||
library_benchmark_group!(name = memcmp; benchmarks = bench_cmp);
|
||||
library_benchmark_group!(name = memcmp, benchmarks = [bench_cmp]);
|
||||
}
|
||||
|
||||
mod mmove {
|
||||
@@ -489,7 +489,7 @@ fn backward_move((len, spread, mut buf): (usize, usize, AlignedSlice)) {
|
||||
}
|
||||
}
|
||||
|
||||
library_benchmark_group!(name = memmove; benchmarks = forward_move, backward_move);
|
||||
library_benchmark_group!(name = memmove, benchmarks = [forward_move, backward_move]);
|
||||
}
|
||||
|
||||
use mcmp::memcmp;
|
||||
@@ -497,4 +497,4 @@ fn backward_move((len, spread, mut buf): (usize, usize, AlignedSlice)) {
|
||||
use mmove::memmove;
|
||||
use mset::memset;
|
||||
|
||||
main!(library_benchmark_groups = memcpy, memset, memcmp, memmove);
|
||||
main!(library_benchmark_groups = [memcpy, memset, memcmp, memmove]);
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#[path = "../libm/configure.rs"]
|
||||
mod configure;
|
||||
|
||||
use std::collections::HashSet;
|
||||
|
||||
mod builtins_configure {
|
||||
include!("../compiler-builtins/configure.rs");
|
||||
}
|
||||
use configure::{Config, Library, set_cfg};
|
||||
|
||||
/// Features to enable
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
enum Feature {
|
||||
enum SetCfg {
|
||||
NoSysF128,
|
||||
NoSysF128IntConvert,
|
||||
NoSysF16,
|
||||
@@ -14,7 +15,15 @@ enum Feature {
|
||||
NoSysF16F128Convert,
|
||||
}
|
||||
|
||||
impl Feature {
|
||||
impl SetCfg {
|
||||
const ALL: &[Self] = &[
|
||||
Self::NoSysF128,
|
||||
Self::NoSysF128IntConvert,
|
||||
Self::NoSysF16,
|
||||
Self::NoSysF16F64Convert,
|
||||
Self::NoSysF16F128Convert,
|
||||
];
|
||||
|
||||
fn implies(self) -> &'static [Self] {
|
||||
match self {
|
||||
Self::NoSysF128 => [Self::NoSysF128IntConvert, Self::NoSysF16F128Convert].as_slice(),
|
||||
@@ -24,96 +33,89 @@ fn implies(self) -> &'static [Self] {
|
||||
Self::NoSysF16F128Convert => [].as_slice(),
|
||||
}
|
||||
}
|
||||
|
||||
fn name(self) -> &'static str {
|
||||
match self {
|
||||
Self::NoSysF128 => "no_sys_f128",
|
||||
Self::NoSysF128IntConvert => "no_sys_f128_int_convert",
|
||||
Self::NoSysF16F64Convert => "no_sys_f16_f64_convert",
|
||||
Self::NoSysF16F128Convert => "no_sys_f16_f128_convert",
|
||||
Self::NoSysF16 => "no_sys_f16",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("cargo::rerun-if-changed=../configure.rs");
|
||||
println!("cargo::rerun-if-changed=../libm/configure.rs");
|
||||
|
||||
let target = builtins_configure::Target::from_env();
|
||||
let mut features = HashSet::new();
|
||||
let cfg = Config::from_env(Library::BuiltinsTest);
|
||||
configure::emit(&cfg);
|
||||
|
||||
let mut to_set = HashSet::new();
|
||||
|
||||
// These platforms do not have f128 symbols available in their system libraries, so
|
||||
// skip related tests.
|
||||
if target.arch == "arm"
|
||||
|| target.vendor == "apple"
|
||||
|| target.env == "msvc"
|
||||
if cfg.target_arch == "arm"
|
||||
|| cfg.target_vendor == "apple"
|
||||
|| cfg.target_env == "msvc"
|
||||
// GCC and LLVM disagree on the ABI of `f16` and `f128` with MinGW. See
|
||||
// <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115054>.
|
||||
|| (target.os == "windows" && target.env == "gnu")
|
||||
|| (cfg.target_os == "windows" && cfg.target_env == "gnu")
|
||||
// FIXME(llvm): There is an ABI incompatibility between GCC and Clang on 32-bit x86.
|
||||
// See <https://github.com/llvm/llvm-project/issues/77401>.
|
||||
|| target.arch == "x86"
|
||||
|| cfg.target_arch == "x86"
|
||||
// 32-bit PowerPC and 64-bit LE gets code generated that Qemu cannot handle. See
|
||||
// <https://github.com/rust-lang/compiler-builtins/pull/606#issuecomment-2105635926>.
|
||||
|| target.arch == "powerpc"
|
||||
|| target.arch == "powerpc64le"
|
||||
|| cfg.target_arch == "powerpc"
|
||||
|| cfg.target_arch == "powerpc64le"
|
||||
// FIXME: We get different results from the builtin functions. See
|
||||
// <https://github.com/rust-lang/compiler-builtins/pull/606#issuecomment-2105657287>.
|
||||
|| target.arch == "powerpc64"
|
||||
|| cfg.target_arch == "powerpc64"
|
||||
{
|
||||
features.insert(Feature::NoSysF128);
|
||||
to_set.insert(SetCfg::NoSysF128);
|
||||
}
|
||||
|
||||
if target.arch == "x86" {
|
||||
if cfg.target_arch == "x86" {
|
||||
// 32-bit x86 does not have `__fixunstfti`/`__fixtfti` but does have everything else
|
||||
features.insert(Feature::NoSysF128IntConvert);
|
||||
to_set.insert(SetCfg::NoSysF128IntConvert);
|
||||
// FIXME: 32-bit x86 has a bug in `f128 -> f16` system libraries
|
||||
features.insert(Feature::NoSysF16F128Convert);
|
||||
to_set.insert(SetCfg::NoSysF16F128Convert);
|
||||
}
|
||||
|
||||
// These platforms do not have f16 symbols available in their system libraries, so
|
||||
// skip related tests. Most of these are missing `f16 <-> f32` conversion routines.
|
||||
if (target.arch == "aarch64" && target.os == "linux")
|
||||
|| target.arch.starts_with("arm")
|
||||
|| target.arch == "powerpc"
|
||||
|| target.arch == "powerpc64"
|
||||
|| target.arch == "powerpc64le"
|
||||
|| target.arch == "loongarch64"
|
||||
|| (target.arch == "x86" && !target.has_feature("sse"))
|
||||
|| target.os == "windows"
|
||||
if (cfg.target_arch == "aarch64" && cfg.target_os == "linux")
|
||||
|| cfg.target_arch.starts_with("arm")
|
||||
|| cfg.target_arch == "powerpc"
|
||||
|| cfg.target_arch == "powerpc64"
|
||||
|| cfg.target_arch == "powerpc64le"
|
||||
|| cfg.target_arch == "loongarch64"
|
||||
|| (cfg.target_arch == "x86" && !cfg.has_target_feature("sse"))
|
||||
|| cfg.target_os == "windows"
|
||||
// Linking says "error: function signature mismatch: __extendhfsf2" and seems to
|
||||
// think the signature is either `(i32) -> f32` or `(f32) -> f32`. See
|
||||
// <https://github.com/llvm/llvm-project/issues/96438>.
|
||||
|| target.arch == "wasm32"
|
||||
|| target.arch == "wasm64"
|
||||
|| cfg.target_arch == "wasm32"
|
||||
|| cfg.target_arch == "wasm64"
|
||||
{
|
||||
features.insert(Feature::NoSysF16);
|
||||
to_set.insert(SetCfg::NoSysF16);
|
||||
}
|
||||
|
||||
// These platforms are missing either `__extendhfdf2` or `__truncdfhf2`.
|
||||
if target.vendor == "apple" || target.os == "windows" {
|
||||
features.insert(Feature::NoSysF16F64Convert);
|
||||
if cfg.target_vendor == "apple" || cfg.target_os == "windows" {
|
||||
to_set.insert(SetCfg::NoSysF16F64Convert);
|
||||
}
|
||||
|
||||
// Add implied features. Collection is required for borrows.
|
||||
features.extend(
|
||||
features
|
||||
to_set.extend(
|
||||
to_set
|
||||
.iter()
|
||||
.flat_map(|x| x.implies())
|
||||
.copied()
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
for feature in features {
|
||||
let (name, warning) = match feature {
|
||||
Feature::NoSysF128 => ("no-sys-f128", "using apfloat fallback for f128"),
|
||||
Feature::NoSysF128IntConvert => (
|
||||
"no-sys-f128-int-convert",
|
||||
"using apfloat fallback for f128 <-> int conversions",
|
||||
),
|
||||
Feature::NoSysF16F64Convert => (
|
||||
"no-sys-f16-f64-convert",
|
||||
"using apfloat fallback for f16 <-> f64 conversions",
|
||||
),
|
||||
Feature::NoSysF16F128Convert => (
|
||||
"no-sys-f16-f128-convert",
|
||||
"using apfloat fallback for f16 <-> f128 conversions",
|
||||
),
|
||||
Feature::NoSysF16 => ("no-sys-f16", "using apfloat fallback for f16"),
|
||||
};
|
||||
println!("cargo:warning={warning}");
|
||||
println!("cargo:rustc-cfg=feature=\"{name}\"");
|
||||
for cfg in SetCfg::ALL {
|
||||
set_cfg(cfg.name(), to_set.contains(cfg));
|
||||
}
|
||||
|
||||
builtins_configure::configure_aliases(&target);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use alloc::vec::Vec;
|
||||
use core::cell::RefCell;
|
||||
|
||||
use compiler_builtins::float::Float;
|
||||
use compiler_builtins::support::Float;
|
||||
|
||||
/// Fuzz with these many items to ensure equal functions
|
||||
pub const CHECK_ITER_ITEMS: u32 = 10_000;
|
||||
@@ -43,7 +43,7 @@ pub fn skip_sys_checks(test_name: &str) -> bool {
|
||||
return true;
|
||||
}
|
||||
|
||||
if cfg!(x86_no_sse) && X86_NO_SSE_SKIPPED.contains(&test_name) {
|
||||
if cfg!(x86_no_sse2) && X86_NO_SSE_SKIPPED.contains(&test_name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,7 @@
|
||||
pub mod bench;
|
||||
extern crate alloc;
|
||||
|
||||
use compiler_builtins::float::Float;
|
||||
use compiler_builtins::int::{Int, MinInt};
|
||||
use compiler_builtins::support::{Float, Int, MinInt};
|
||||
use rand_xoshiro::Xoshiro128StarStar;
|
||||
use rand_xoshiro::rand_core::{Rng, SeedableRng};
|
||||
|
||||
@@ -245,18 +244,18 @@ fn fuzz_float_step<F: Float>(rng: &mut Xoshiro128StarStar, f: &mut F) {
|
||||
let sign = (rng32 & 1) != 0;
|
||||
|
||||
// exponent fuzzing. Only 4 bits for the selector needed.
|
||||
let ones = (F::Int::ONE << F::EXP_BITS) - F::Int::ONE;
|
||||
let ones = F::EXP_SAT;
|
||||
let r0 = (rng32 >> 1) % F::EXP_BITS;
|
||||
let r1 = (rng32 >> 5) % F::EXP_BITS;
|
||||
// custom rotate shift. Note that `F::Int` is unsigned, so we can shift right without smearing
|
||||
// the sign bit.
|
||||
let mask = if r1 == 0 {
|
||||
ones.wrapping_shr(r0)
|
||||
ones >> r0
|
||||
} else {
|
||||
let tmp = ones.wrapping_shr(r0);
|
||||
(tmp.wrapping_shl(r1) | tmp.wrapping_shr(F::EXP_BITS - r1)) & ones
|
||||
let tmp = ones >> r0;
|
||||
((tmp << r1) | (tmp >> (F::EXP_BITS - r1))) & ones
|
||||
};
|
||||
let mut exp = (f.to_bits() & F::EXP_MASK) >> F::SIG_BITS;
|
||||
let mut exp = f.ex();
|
||||
match (rng32 >> 9) % 4 {
|
||||
0 => exp |= mask,
|
||||
1 => exp &= mask,
|
||||
@@ -274,13 +273,13 @@ fn fuzz_float_step<F: Float>(rng: &mut Xoshiro128StarStar, f: &mut F) {
|
||||
macro_rules! float_edge_cases {
|
||||
($F:ident, $case:ident, $inner:block) => {
|
||||
for exponent in [
|
||||
F::Int::ZERO,
|
||||
F::Int::ONE,
|
||||
F::Int::ONE << (F::EXP_BITS / 2),
|
||||
(F::Int::ONE << (F::EXP_BITS - 1)) - F::Int::ONE,
|
||||
F::Int::ONE << (F::EXP_BITS - 1),
|
||||
(F::Int::ONE << (F::EXP_BITS - 1)) + F::Int::ONE,
|
||||
(F::Int::ONE << F::EXP_BITS) - F::Int::ONE,
|
||||
0,
|
||||
1,
|
||||
1 << (F::EXP_BITS / 2),
|
||||
(1 << (F::EXP_BITS - 1)) - 1,
|
||||
1 << (F::EXP_BITS - 1),
|
||||
(1 << (F::EXP_BITS - 1)) + 1,
|
||||
(1 << F::EXP_BITS) - 1,
|
||||
]
|
||||
.iter()
|
||||
{
|
||||
|
||||
@@ -87,7 +87,8 @@ macro_rules! float_sum {
|
||||
#[test]
|
||||
fn $fn_add() {
|
||||
use core::ops::{Add, Sub};
|
||||
use compiler_builtins::float::{{add::$fn_add, sub::$fn_sub}, Float};
|
||||
use compiler_builtins::float::{add::$fn_add, sub::$fn_sub};
|
||||
use compiler_builtins::support::Float;
|
||||
|
||||
fuzz_float_2(N, |x: $f, y: $f| {
|
||||
let add0 = apfloat_fallback!($f, $apfloat_ty, $sys_available, Add::add, x, y);
|
||||
@@ -112,7 +113,7 @@ fn $fn_add() {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(x86_no_sse))]
|
||||
#[cfg(not(x86_no_sse2))]
|
||||
mod float_addsub {
|
||||
use super::*;
|
||||
|
||||
@@ -127,15 +128,15 @@ mod float_addsub {
|
||||
}
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg(not(x86_no_sse))]
|
||||
#[cfg(not(x86_no_sse2))]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
float_sum! {
|
||||
f128, __addtf3, __subtf3, Quad, not(feature = "no-sys-f128");
|
||||
f128, __addtf3, __subtf3, Quad, not(no_sys_f128);
|
||||
}
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
|
||||
float_sum! {
|
||||
f128, __addkf3, __subkf3, Quad, not(feature = "no-sys-f128");
|
||||
f128, __addkf3, __subkf3, Quad, not(no_sys_f128);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,134 +0,0 @@
|
||||
use compiler_builtins::int::{HInt, MinInt, i256, u256};
|
||||
|
||||
const LOHI_SPLIT: u128 = 0xaaaaaaaaaaaaaaaaffffffffffffffff;
|
||||
|
||||
/// Print a `u256` as hex since we can't add format implementations
|
||||
fn hexu(v: u256) -> String {
|
||||
format!(
|
||||
"0x{:016x}{:016x}{:016x}{:016x}",
|
||||
v.0[3], v.0[2], v.0[1], v.0[0]
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn widen_u128() {
|
||||
assert_eq!(u128::MAX.widen(), u256([u64::MAX, u64::MAX, 0, 0]));
|
||||
assert_eq!(
|
||||
LOHI_SPLIT.widen(),
|
||||
u256([u64::MAX, 0xaaaaaaaaaaaaaaaa, 0, 0])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn widen_i128() {
|
||||
assert_eq!((-1i128).widen(), u256::MAX.signed());
|
||||
assert_eq!(
|
||||
(LOHI_SPLIT as i128).widen(),
|
||||
i256([u64::MAX, 0xaaaaaaaaaaaaaaaa, u64::MAX, u64::MAX])
|
||||
);
|
||||
assert_eq!((-1i128).zero_widen().unsigned(), (u128::MAX).widen());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn widen_mul_u128() {
|
||||
let tests = [
|
||||
(u128::MAX / 2, 2_u128, u256([u64::MAX - 1, u64::MAX, 0, 0])),
|
||||
(u128::MAX, 2_u128, u256([u64::MAX - 1, u64::MAX, 1, 0])),
|
||||
(u128::MAX, u128::MAX, u256([1, 0, u64::MAX - 1, u64::MAX])),
|
||||
(u128::MIN, u128::MIN, u256::ZERO),
|
||||
(1234, 0, u256::ZERO),
|
||||
(0, 1234, u256::ZERO),
|
||||
];
|
||||
|
||||
let mut errors = Vec::new();
|
||||
for (i, (a, b, exp)) in tests.iter().copied().enumerate() {
|
||||
let res = a.widen_mul(b);
|
||||
let res_z = a.zero_widen_mul(b);
|
||||
assert_eq!(res, res_z);
|
||||
if res != exp {
|
||||
errors.push((i, a, b, exp, res));
|
||||
}
|
||||
}
|
||||
|
||||
for (i, a, b, exp, res) in &errors {
|
||||
eprintln!(
|
||||
"FAILURE ({i}): {a:#034x} * {b:#034x} = {} got {}",
|
||||
hexu(*exp),
|
||||
hexu(*res)
|
||||
);
|
||||
}
|
||||
assert!(errors.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn not_u128() {
|
||||
assert_eq!(!u256::ZERO, u256::MAX);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shr_u128() {
|
||||
let only_low = [
|
||||
1,
|
||||
u16::MAX.into(),
|
||||
u32::MAX.into(),
|
||||
u64::MAX.into(),
|
||||
u128::MAX,
|
||||
];
|
||||
|
||||
let mut errors = Vec::new();
|
||||
|
||||
for a in only_low {
|
||||
for perturb in 0..10 {
|
||||
let a = a.saturating_add(perturb);
|
||||
for shift in 0..128 {
|
||||
let res = a.widen() >> shift;
|
||||
let expected = (a >> shift).widen();
|
||||
if res != expected {
|
||||
errors.push((a.widen(), shift, res, expected));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let check = [
|
||||
(
|
||||
u256::MAX,
|
||||
1,
|
||||
u256([u64::MAX, u64::MAX, u64::MAX, u64::MAX >> 1]),
|
||||
),
|
||||
(
|
||||
u256::MAX,
|
||||
5,
|
||||
u256([u64::MAX, u64::MAX, u64::MAX, u64::MAX >> 5]),
|
||||
),
|
||||
(u256::MAX, 63, u256([u64::MAX, u64::MAX, u64::MAX, 1])),
|
||||
(u256::MAX, 64, u256([u64::MAX, u64::MAX, u64::MAX, 0])),
|
||||
(u256::MAX, 65, u256([u64::MAX, u64::MAX, u64::MAX >> 1, 0])),
|
||||
(u256::MAX, 127, u256([u64::MAX, u64::MAX, 1, 0])),
|
||||
(u256::MAX, 128, u256([u64::MAX, u64::MAX, 0, 0])),
|
||||
(u256::MAX, 129, u256([u64::MAX, u64::MAX >> 1, 0, 0])),
|
||||
(u256::MAX, 191, u256([u64::MAX, 1, 0, 0])),
|
||||
(u256::MAX, 192, u256([u64::MAX, 0, 0, 0])),
|
||||
(u256::MAX, 193, u256([u64::MAX >> 1, 0, 0, 0])),
|
||||
(u256::MAX, 191, u256([u64::MAX, 1, 0, 0])),
|
||||
(u256::MAX, 254, u256([0b11, 0, 0, 0])),
|
||||
(u256::MAX, 255, u256([1, 0, 0, 0])),
|
||||
];
|
||||
|
||||
for (input, shift, expected) in check {
|
||||
let res = input >> shift;
|
||||
if res != expected {
|
||||
errors.push((input, shift, res, expected));
|
||||
}
|
||||
}
|
||||
|
||||
for (a, b, res, expected) in &errors {
|
||||
eprintln!(
|
||||
"FAILURE: {} >> {b} = {} got {}",
|
||||
hexu(*a),
|
||||
hexu(*expected),
|
||||
hexu(*res),
|
||||
);
|
||||
}
|
||||
assert!(errors.is_empty());
|
||||
}
|
||||
@@ -125,19 +125,19 @@ fn cmp_f128() {
|
||||
|
||||
fuzz_float_2(N, |x: f128, y: f128| {
|
||||
let x_is_nan = apfloat_fallback!(
|
||||
f128, Quad, not(feature = "no-sys-f128"),
|
||||
f128, Quad, not(no_sys_f128),
|
||||
|x: FloatTy| x.is_nan() => no_convert,
|
||||
x
|
||||
);
|
||||
let y_is_nan = apfloat_fallback!(
|
||||
f128, Quad, not(feature = "no-sys-f128"),
|
||||
f128, Quad, not(no_sys_f128),
|
||||
|x: FloatTy| x.is_nan() => no_convert,
|
||||
y
|
||||
);
|
||||
|
||||
assert_eq!(__unordtf2(x, y) != 0, x_is_nan || y_is_nan);
|
||||
|
||||
cmp!(f128, x, y, Quad, not(feature = "no-sys-f128"),
|
||||
cmp!(f128, x, y, Quad, not(no_sys_f128),
|
||||
1, __lttf2;
|
||||
1, __letf2;
|
||||
1, __eqtf2;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#![allow(unused_macros)]
|
||||
|
||||
use builtins_test::*;
|
||||
use compiler_builtins::float::Float;
|
||||
use compiler_builtins::support::Float;
|
||||
use rustc_apfloat::{Float as _, FloatConvert as _};
|
||||
|
||||
mod i_to_f {
|
||||
@@ -18,7 +18,7 @@ macro_rules! i_to_f {
|
||||
#[test]
|
||||
fn $fn() {
|
||||
use compiler_builtins::float::conv::$fn;
|
||||
use compiler_builtins::int::Int;
|
||||
use compiler_builtins::support::Int;
|
||||
|
||||
fuzz(N, |x: $i_ty| {
|
||||
let f0 = apfloat_fallback!(
|
||||
@@ -27,7 +27,7 @@ fn $fn() {
|
||||
// When the builtin is not available, we need to use a different conversion
|
||||
// method (since apfloat doesn't support `as` casting).
|
||||
|x: $i_ty| {
|
||||
use compiler_builtins::int::MinInt;
|
||||
use compiler_builtins::support::MinInt;
|
||||
|
||||
let apf = if <$i_ty>::SIGNED {
|
||||
FloatTy::from_i128(x.try_into().unwrap()).value
|
||||
@@ -117,7 +117,7 @@ fn $fn() {
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
i_to_f! { f128, Quad, not(feature = "no-sys-f128-int-convert"),
|
||||
i_to_f! { f128, Quad, not(no_sys_f128_int_convert),
|
||||
u32, __floatunsitf;
|
||||
i32, __floatsitf;
|
||||
u64, __floatunditf;
|
||||
@@ -128,7 +128,7 @@ fn $fn() {
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
|
||||
i_to_f! { f128, Quad, not(feature = "no-sys-f128-int-convert"),
|
||||
i_to_f! { f128, Quad, not(no_sys_f128_int_convert),
|
||||
u32, __floatunsikf;
|
||||
i32, __floatsikf;
|
||||
u64, __floatundikf;
|
||||
@@ -155,7 +155,7 @@ macro_rules! f_to_i {
|
||||
// When the builtin is not available, we need to use a different conversion
|
||||
// method (since apfloat doesn't support `as` casting).
|
||||
|x: $f_ty| {
|
||||
use compiler_builtins::int::MinInt;
|
||||
use compiler_builtins::support::MinInt;
|
||||
|
||||
let apf = FloatTy::from_bits(x.to_bits().into());
|
||||
let bits: usize = <$i_ty>::BITS.try_into().unwrap();
|
||||
@@ -236,7 +236,7 @@ fn f128_to_int() {
|
||||
x,
|
||||
f128,
|
||||
Quad,
|
||||
not(feature = "no-sys-f128-int-convert"),
|
||||
not(no_sys_f128_int_convert),
|
||||
u32, __fixunstfsi;
|
||||
u64, __fixunstfdi;
|
||||
u128, __fixunstfti;
|
||||
@@ -259,7 +259,8 @@ macro_rules! f_to_f {
|
||||
) => {$(
|
||||
#[test]
|
||||
fn $fn() {
|
||||
use compiler_builtins::float::{$mod::$fn, Float};
|
||||
use compiler_builtins::float::$mod::$fn;
|
||||
use compiler_builtins::support::Float;
|
||||
use rustc_apfloat::ieee::{$from_ap_ty, $to_ap_ty};
|
||||
|
||||
fuzz_float(N, |x: $from_ty| {
|
||||
@@ -308,12 +309,12 @@ mod extend {
|
||||
)))]
|
||||
f_to_f! {
|
||||
extend,
|
||||
f16 => f32, Half => Single, __extendhfsf2, not(feature = "no-sys-f16");
|
||||
f16 => f32, Half => Single, __gnu_h2f_ieee, not(feature = "no-sys-f16");
|
||||
f16 => f64, Half => Double, __extendhfdf2, not(feature = "no-sys-f16-f64-convert");
|
||||
f16 => f128, Half => Quad, __extendhftf2, not(feature = "no-sys-f16-f128-convert");
|
||||
f32 => f128, Single => Quad, __extendsftf2, not(feature = "no-sys-f128");
|
||||
f64 => f128, Double => Quad, __extenddftf2, not(feature = "no-sys-f128");
|
||||
f16 => f32, Half => Single, __extendhfsf2, not(no_sys_f16);
|
||||
f16 => f32, Half => Single, __gnu_h2f_ieee, not(no_sys_f16);
|
||||
f16 => f64, Half => Double, __extendhfdf2, not(no_sys_f16_f64_convert);
|
||||
f16 => f128, Half => Quad, __extendhftf2, not(no_sys_f16_f128_convert);
|
||||
f32 => f128, Single => Quad, __extendsftf2, not(no_sys_f128);
|
||||
f64 => f128, Double => Quad, __extenddftf2, not(no_sys_f128);
|
||||
}
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
@@ -321,8 +322,8 @@ mod extend {
|
||||
f_to_f! {
|
||||
extend,
|
||||
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
|
||||
f32 => f128, Single => Quad, __extendsfkf2, not(feature = "no-sys-f128");
|
||||
f64 => f128, Double => Quad, __extenddfkf2, not(feature = "no-sys-f128");
|
||||
f32 => f128, Single => Quad, __extendsfkf2, not(no_sys_f128);
|
||||
f64 => f128, Double => Quad, __extenddfkf2, not(no_sys_f128);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,12 +343,12 @@ mod trunc {
|
||||
)))]
|
||||
f_to_f! {
|
||||
trunc,
|
||||
f32 => f16, Single => Half, __truncsfhf2, not(feature = "no-sys-f16");
|
||||
f32 => f16, Single => Half, __gnu_f2h_ieee, not(feature = "no-sys-f16");
|
||||
f64 => f16, Double => Half, __truncdfhf2, not(feature = "no-sys-f16-f64-convert");
|
||||
f128 => f16, Quad => Half, __trunctfhf2, not(feature = "no-sys-f16-f128-convert");
|
||||
f128 => f32, Quad => Single, __trunctfsf2, not(feature = "no-sys-f128");
|
||||
f128 => f64, Quad => Double, __trunctfdf2, not(feature = "no-sys-f128");
|
||||
f32 => f16, Single => Half, __truncsfhf2, not(no_sys_f16);
|
||||
f32 => f16, Single => Half, __gnu_f2h_ieee, not(no_sys_f16);
|
||||
f64 => f16, Double => Half, __truncdfhf2, not(no_sys_f16_f64_convert);
|
||||
f128 => f16, Quad => Half, __trunctfhf2, not(no_sys_f16_f128_convert);
|
||||
f128 => f32, Quad => Single, __trunctfsf2, not(no_sys_f128);
|
||||
f128 => f64, Quad => Double, __trunctfdf2, not(no_sys_f128);
|
||||
}
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
@@ -355,7 +356,7 @@ mod trunc {
|
||||
f_to_f! {
|
||||
trunc,
|
||||
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
|
||||
f128 => f32, Quad => Single, __trunckfsf2, not(feature = "no-sys-f128");
|
||||
f128 => f64, Quad => Double, __trunckfdf2, not(feature = "no-sys-f128");
|
||||
f128 => f32, Quad => Single, __trunckfsf2, not(no_sys_f128);
|
||||
f128 => f64, Quad => Double, __trunckfdf2, not(no_sys_f128);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,8 @@ macro_rules! float {
|
||||
$(
|
||||
#[test]
|
||||
fn $fn() {
|
||||
use compiler_builtins::float::{div::$fn, Float};
|
||||
use compiler_builtins::float::div::$fn;
|
||||
use compiler_builtins::support::Float;
|
||||
use core::ops::Div;
|
||||
|
||||
fuzz_float_2(N, |x: $f, y: $f| {
|
||||
@@ -138,7 +139,7 @@ fn $fn() {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(x86_no_sse))]
|
||||
#[cfg(not(x86_no_sse2))]
|
||||
mod float_div {
|
||||
use super::*;
|
||||
|
||||
@@ -153,12 +154,12 @@ mod float_div {
|
||||
f128, __divtf3, Quad,
|
||||
// FIXME(llvm): there is a bug in LLVM rt.
|
||||
// See <https://github.com/llvm/llvm-project/issues/91840>.
|
||||
not(any(feature = "no-sys-f128", all(target_arch = "aarch64", target_os = "linux")));
|
||||
not(any(no_sys_f128, all(target_arch = "aarch64", target_os = "linux")));
|
||||
}
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
|
||||
float! {
|
||||
f128, __divkf3, Quad, not(feature = "no-sys-f128");
|
||||
f128, __divkf3, Quad, not(no_sys_f128);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#![allow(unused_macros, unused_features)]
|
||||
#![cfg_attr(f128_enabled, feature(f128))]
|
||||
|
||||
#[cfg_attr(x86_no_sse, allow(unused))]
|
||||
#[cfg_attr(x86_no_sse2, allow(unused))]
|
||||
use builtins_test::*;
|
||||
|
||||
// This is approximate because of issues related to
|
||||
@@ -16,7 +16,8 @@ macro_rules! pow {
|
||||
#[cfg($sys_available)]
|
||||
fn $fn() {
|
||||
use compiler_builtins::float::pow::$fn;
|
||||
use compiler_builtins::float::Float;
|
||||
use compiler_builtins::support::Float;
|
||||
|
||||
fuzz_float_2(N, |x: $f, y: $f| {
|
||||
if !(Float::is_subnormal(x) || Float::is_subnormal(y) || x.is_nan()) {
|
||||
let n = y.to_bits() & !<$f as Float>::SIG_MASK;
|
||||
@@ -52,7 +53,7 @@ fn $fn() {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(x86_no_sse))] // FIXME(i586): failure for powidf2
|
||||
#[cfg(not(x86_no_sse2))] // FIXME(i586): failure for powidf2
|
||||
pow! {
|
||||
f32, 1e-4, __powisf2, all();
|
||||
f64, 1e-12, __powidf2, all();
|
||||
@@ -61,11 +62,11 @@ fn $fn() {
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
pow! {
|
||||
f128, 1e-36, __powitf2, not(feature = "no-sys-f128");
|
||||
f128, 1e-36, __powitf2, not(no_sys_f128);
|
||||
}
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
|
||||
pow! {
|
||||
f128, 1e-36, __powikf2, not(feature = "no-sys-f128");
|
||||
f128, 1e-36, __powikf2, not(no_sys_f128);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
#![allow(unused_features)]
|
||||
#![feature(decl_macro)] // so we can use pub(super)
|
||||
#![feature(macro_metavar_expr_concat)]
|
||||
#![cfg(all(target_arch = "aarch64", feature = "mangled-names"))]
|
||||
#![cfg(target_arch = "aarch64")]
|
||||
|
||||
use std::sync::Mutex;
|
||||
|
||||
use compiler_builtins::aarch64_outline_atomics::{get_have_lse_atomics, set_have_lse_atomics};
|
||||
use compiler_builtins::int::{Int, MinInt};
|
||||
use compiler_builtins::support::{Int, MinInt};
|
||||
use compiler_builtins::{foreach_bytes, foreach_ordering};
|
||||
|
||||
#[track_caller]
|
||||
|
||||
@@ -96,7 +96,8 @@ macro_rules! float_mul {
|
||||
$(
|
||||
#[test]
|
||||
fn $fn() {
|
||||
use compiler_builtins::float::{mul::$fn, Float};
|
||||
use compiler_builtins::float::mul::$fn;
|
||||
use compiler_builtins::support::Float;
|
||||
use core::ops::Mul;
|
||||
|
||||
fuzz_float_2(N, |x: $f, y: $f| {
|
||||
@@ -114,7 +115,7 @@ fn $fn() {
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(not(x86_no_sse))]
|
||||
#[cfg(not(x86_no_sse2))]
|
||||
mod float_mul {
|
||||
use super::*;
|
||||
|
||||
@@ -132,7 +133,7 @@ mod float_mul {
|
||||
}
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg(not(x86_no_sse))]
|
||||
#[cfg(not(x86_no_sse2))]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
mod float_mul_f128 {
|
||||
use super::*;
|
||||
@@ -141,7 +142,7 @@ mod float_mul_f128 {
|
||||
f128, __multf3, Quad,
|
||||
// FIXME(llvm): there is a bug in LLVM rt.
|
||||
// See <https://github.com/llvm/llvm-project/issues/91840>.
|
||||
not(any(feature = "no-sys-f128", all(target_arch = "aarch64", target_os = "linux")));
|
||||
not(any(no_sys_f128, all(target_arch = "aarch64", target_os = "linux")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,6 +152,6 @@ mod float_mul_f128_ppc {
|
||||
use super::*;
|
||||
|
||||
float_mul! {
|
||||
f128, __mulkf3, Quad, not(feature = "no-sys-f128");
|
||||
f128, __mulkf3, Quad, not(no_sys_f128);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,12 +26,20 @@ tag="$(echo "$target" | cut -d'-' -f1)"
|
||||
# after the first run with gungraun.
|
||||
[ -d "iai-home" ] && mv "iai-home" "$gungraun_home"
|
||||
|
||||
failed="0"
|
||||
|
||||
# Run benchmarks once
|
||||
function run_icount_benchmarks() {
|
||||
cargo_args=(
|
||||
"--target" "$target"
|
||||
"--bench" "*icount*"
|
||||
"--no-default-features"
|
||||
"--features" "unstable,unstable-float,icount"
|
||||
"--features" "unstable unstable-float icount"
|
||||
# Enable unmangled-names so our compiler-builtins gets used for
|
||||
# intrinsics. This makes performance impacts of c-b changes show up
|
||||
# in libm benchmarks and gives us a better idea of what will happen
|
||||
# in std (e.g. speedups in __addtf3 will show up in fmaf128).
|
||||
"--features" "compiler_builtins/unmangled-names"
|
||||
)
|
||||
|
||||
gungraun_args=(
|
||||
@@ -65,13 +73,18 @@ function run_icount_benchmarks() {
|
||||
# Disregard regressions after merge
|
||||
echo "Benchmarks completed with regressions; ignoring (not in a PR)"
|
||||
else
|
||||
./ci/ci-util.py handle-bench-regressions "$PR_NUMBER"
|
||||
./ci/ci-util.py handle-bench-regressions "$PR_NUMBER" || failed="1"
|
||||
fi
|
||||
}
|
||||
|
||||
# Run once with softfloats, once with arch instructions enabled
|
||||
run_icount_benchmarks --features force-soft-floats -- --save-baseline=softfloat
|
||||
run_icount_benchmarks -- --save-baseline=hardfloat
|
||||
run_icount_benchmarks -- --save-baseline=arch_disabled
|
||||
run_icount_benchmarks --features arch -- --save-baseline=arch_enabled
|
||||
|
||||
if [ "$failed" != "0" ]; then
|
||||
echo "One or more benchmarks failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Name and tar the new baseline
|
||||
name="baseline-icount-$tag-$(date -u +'%Y%m%d%H%M')-${GITHUB_SHA:0:12}"
|
||||
|
||||
@@ -6,4 +6,4 @@
|
||||
export LIBM_SEED=benchesbenchesbenchesbencheswoo!
|
||||
cargo bench --package libm-test \
|
||||
--no-default-features \
|
||||
--features walltime,short-benchmarks,build-musl,libm/force-soft-floats
|
||||
--features walltime,short-benchmarks,build-musl
|
||||
|
||||
@@ -361,6 +361,10 @@ def base_name(name: str) -> tuple[str, str]:
|
||||
return (name.rstrip("f"), "f32")
|
||||
elif name.endswith("f16"):
|
||||
return (name.rstrip("f16"), "f16")
|
||||
elif name.endswith("f32"):
|
||||
return (name.rstrip("f32"), "f32")
|
||||
elif name.endswith("f64"):
|
||||
return (name.rstrip("f64"), "f64")
|
||||
elif name.endswith("f128"):
|
||||
return (name.rstrip("f128"), "f128")
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
gcc libc6-dev qemu-user ca-certificates \
|
||||
gcc-riscv64-linux-gnu libc6-dev-riscv64-cross \
|
||||
qemu-system-riscv64
|
||||
qemu-system-riscv
|
||||
|
||||
ENV TOOLCHAIN_PREFIX=riscv64-linux-gnu-
|
||||
ENV CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG IMAGE=ubuntu:25.10
|
||||
ARG IMAGE=ubuntu:26.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
||||
@@ -6,5 +6,5 @@ set -eux
|
||||
|
||||
rust_llvm_version=20.1-2025-02-13
|
||||
|
||||
curl -L -o code.tar.gz "https://github.com/rust-lang/llvm-project/archive/rustc/${rust_llvm_version}.tar.gz"
|
||||
curl -L --retry 3 -o code.tar.gz "https://github.com/rust-lang/llvm-project/archive/rustc/${rust_llvm_version}.tar.gz"
|
||||
tar xzf code.tar.gz --strip-components 1 llvm-project-rustc-${rust_llvm_version}/compiler-rt
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
# Install needed dependencies for gungraun.
|
||||
|
||||
set -eux
|
||||
|
||||
target="${1:-}"
|
||||
|
||||
# Needed for gungraun
|
||||
deps=(valgrind gdb libc6-dbg)
|
||||
|
||||
[[ "$target" = *"i686"* ]] && deps+=(gcc-multilib)
|
||||
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y valgrind gdb libc6-dbg # Needed for gungraun
|
||||
sudo apt-get install -y "${deps[@]}"
|
||||
|
||||
rustup update "$BENCHMARK_RUSTC" --no-self-update
|
||||
rustup default "$BENCHMARK_RUSTC"
|
||||
[ -n "$target" ] && rustup target add "$target"
|
||||
|
||||
# Install the version of gungraun-runner that is specified in Cargo.toml
|
||||
gungraun_version="$(cargo metadata --format-version=1 --features icount |
|
||||
jq -r '.packages[] | select(.name == "gungraun").version')"
|
||||
|
||||
@@ -5,7 +5,7 @@ set -eux
|
||||
# compatible with Stacked Borrows.
|
||||
export MIRIFLAGS="-Zmiri-tree-borrows"
|
||||
|
||||
# One target that sets `mem-unaligned` and one that does not,
|
||||
# One target that sets `mem_unaligned` and one that does not,
|
||||
# and a big-endian target.
|
||||
targets=(
|
||||
x86_64-unknown-linux-gnu
|
||||
@@ -13,10 +13,11 @@ targets=(
|
||||
s390x-unknown-linux-gnu
|
||||
)
|
||||
for target in "${targets[@]}"; do
|
||||
# Only run the `mem` tests to avoid this taking too long.
|
||||
# Only run the `mem` tests to avoid this taking too long. Disable default
|
||||
# features to turn off `arch` and avoid inline assembly.
|
||||
cargo miri test \
|
||||
--manifest-path builtins-test/Cargo.toml \
|
||||
--features no-asm \
|
||||
--no-default-features \
|
||||
--target "$target" \
|
||||
-- mem
|
||||
done
|
||||
|
||||
@@ -78,6 +78,7 @@ run() {
|
||||
-e CI \
|
||||
-e CARGO_TARGET_DIR=/builtins-target \
|
||||
-e CARGO_TERM_COLOR \
|
||||
-e LIBM_BUILD_VERBOSE \
|
||||
-e MAY_SKIP_LIBM_CI \
|
||||
-e RUSTFLAGS \
|
||||
-e RUST_BACKTRACE \
|
||||
@@ -97,7 +98,7 @@ if [ "${1:-}" = "--help" ] || [ "$#" -gt 1 ]; then
|
||||
usage: ./ci/run-docker.sh [target]
|
||||
|
||||
you can also set DOCKER_BASE_IMAGE to use something other than the default
|
||||
ubuntu:25.10 (or rustlang/rust:nightly).
|
||||
ubuntu:26.04 (or rustlang/rust:nightly).
|
||||
"
|
||||
exit
|
||||
fi
|
||||
|
||||
@@ -14,7 +14,15 @@ set -x
|
||||
test_cmd=(
|
||||
cargo test
|
||||
--package libm-test
|
||||
--features "build-mpfr,libm/unstable,libm/force-soft-floats"
|
||||
--no-default-features
|
||||
# Don't enable `arch` for extensive tests. Usually anything in asm is
|
||||
# only a single instruction or a small sequence, and we rely on the
|
||||
# vendors to test that for us.
|
||||
#
|
||||
# libm/unstable enables libm/unstable-intrinsics, which means we usually
|
||||
# get the single-instruction ops anyway when we aren't specifically
|
||||
# testing for them.
|
||||
--features "libm-test/build-mpfr libm-test/unstable-float libm/unstable"
|
||||
--profile release-checked
|
||||
)
|
||||
|
||||
|
||||
@@ -20,19 +20,45 @@ if [ "${USING_CONTAINER_RUSTC:-}" = 1 ]; then
|
||||
rustup target add "$target"
|
||||
fi
|
||||
|
||||
# If nextest is available, use that
|
||||
command -v cargo-nextest && nextest=1 || nextest=0
|
||||
if [ "$nextest" = "1" ]; then
|
||||
test_runner=(cargo nextest run --max-fail=20)
|
||||
profile_flag="--cargo-profile"
|
||||
|
||||
# Workaround for https://github.com/nextest-rs/nextest/issues/2066
|
||||
if [ -n "${CARGO_TARGET_DIR:-}" ]; then
|
||||
cfg_file="/tmp/nextest-config.toml"
|
||||
echo "[store]" >> "$cfg_file"
|
||||
echo "dir = \"$CARGO_TARGET_DIR/nextest\"" >> "$cfg_file"
|
||||
test_runner+=(--config-file "$cfg_file")
|
||||
fi
|
||||
|
||||
# Not all configurations have tests to run on wasm
|
||||
[[ "$target" = *"wasm"* ]] && test_runner+=(--no-tests=warn)
|
||||
else
|
||||
test_runner=(cargo test --no-fail-fast)
|
||||
profile_flag="--profile"
|
||||
fi
|
||||
|
||||
# Test our implementation
|
||||
if [ "${BUILD_ONLY:-}" = "1" ]; then
|
||||
echo "no tests to run for build-only targets"
|
||||
else
|
||||
test_builtins=(cargo test --package builtins-test --no-fail-fast --target "$target")
|
||||
test_builtins=(
|
||||
"${test_runner[@]}"
|
||||
--package builtins-test
|
||||
--target "$target"
|
||||
)
|
||||
|
||||
"${test_builtins[@]}"
|
||||
"${test_builtins[@]}" --release
|
||||
"${test_builtins[@]}" --features c
|
||||
"${test_builtins[@]}" --features c --release
|
||||
"${test_builtins[@]}" --features no-asm
|
||||
"${test_builtins[@]}" --features no-asm --release
|
||||
"${test_builtins[@]}" --benches
|
||||
"${test_builtins[@]}" --benches --release
|
||||
"${test_builtins[@]}" --no-default-features
|
||||
"${test_builtins[@]}" --no-default-features --release
|
||||
|
||||
# Validate that having a verbatim path for the target directory works
|
||||
# (trivial to regress using `/` in paths to build artifacts rather than
|
||||
@@ -53,12 +79,14 @@ symcheck+=(-- --build-and-check --target "$target")
|
||||
# Executable section checks are meaningless on no-std targets
|
||||
[[ "$target" == *"-none"* ]] && symcheck+=(--no-os)
|
||||
|
||||
"${symcheck[@]}" -- -p compiler_builtins
|
||||
"${symcheck[@]}" -- -p compiler_builtins --release
|
||||
"${symcheck[@]}" -- -p compiler_builtins --features c
|
||||
"${symcheck[@]}" -- -p compiler_builtins --features c --release
|
||||
"${symcheck[@]}" -- -p compiler_builtins --features no-asm
|
||||
"${symcheck[@]}" -- -p compiler_builtins --features no-asm --release
|
||||
# We only need to check the configurations std may use
|
||||
symcheck_cb_args=(-- --package compiler_builtins --features compiler-builtins)
|
||||
"${symcheck[@]}" "${symcheck_cb_args[@]}"
|
||||
"${symcheck[@]}" "${symcheck_cb_args[@]}" --release
|
||||
"${symcheck[@]}" "${symcheck_cb_args[@]}" --features c
|
||||
"${symcheck[@]}" "${symcheck_cb_args[@]}" --features c --release
|
||||
"${symcheck[@]}" "${symcheck_cb_args[@]}" --no-default-features
|
||||
"${symcheck[@]}" "${symcheck_cb_args[@]}" --no-default-features --release
|
||||
|
||||
run_intrinsics_test() {
|
||||
build_args=(--verbose --manifest-path builtins-test-intrinsics/Cargo.toml)
|
||||
@@ -100,13 +128,13 @@ mflags=()
|
||||
# We enumerate features manually.
|
||||
mflags+=(--no-default-features)
|
||||
|
||||
# Enable arch-specific routines when available.
|
||||
mflags+=(--features arch)
|
||||
|
||||
# Always enable `unstable-float` since it expands available API but does not
|
||||
# change any implementations.
|
||||
mflags+=(--features unstable-float)
|
||||
|
||||
# This is a host program that may not run in containers.
|
||||
mflags+=(--exclude update-api-list)
|
||||
|
||||
# We need to specifically skip tests for musl-math-sys on systems that can't
|
||||
# build musl since otherwise `--all` will activate it.
|
||||
case "$target" in
|
||||
@@ -157,28 +185,7 @@ if [ "${BUILD_ONLY:-}" = "1" ]; then
|
||||
else
|
||||
# symcheck tests need specific env setup, and is already tested above
|
||||
mflags+=(--workspace --exclude symbol-check --target "$target")
|
||||
cmd=(cargo test "${mflags[@]}")
|
||||
profile_flag="--profile"
|
||||
|
||||
# If nextest is available, use that
|
||||
command -v cargo-nextest && nextest=1 || nextest=0
|
||||
if [ "$nextest" = "1" ]; then
|
||||
cmd=(cargo nextest run --max-fail=10)
|
||||
|
||||
# Workaround for https://github.com/nextest-rs/nextest/issues/2066
|
||||
if [ -f /.dockerenv ]; then
|
||||
cfg_file="/tmp/nextest-config.toml"
|
||||
echo "[store]" >> "$cfg_file"
|
||||
echo "dir = \"$CARGO_TARGET_DIR/nextest\"" >> "$cfg_file"
|
||||
cmd+=(--config-file "$cfg_file")
|
||||
fi
|
||||
|
||||
# Not all configurations have tests to run on wasm
|
||||
[[ "$target" = *"wasm"* ]] && cmd+=(--no-tests=warn)
|
||||
|
||||
cmd+=("${mflags[@]}")
|
||||
profile_flag="--cargo-profile"
|
||||
fi
|
||||
cmd=("${test_runner[@]}" "${mflags[@]}")
|
||||
|
||||
# Test once without intrinsics
|
||||
"${cmd[@]}"
|
||||
@@ -191,15 +198,15 @@ else
|
||||
cmd+=(--exclude util --exclude libm-macros)
|
||||
|
||||
# Test once with intrinsics enabled
|
||||
"${cmd[@]}" --features unstable-intrinsics
|
||||
"${cmd[@]}" --features unstable-intrinsics --benches
|
||||
"${cmd[@]}" --features arch,unstable-intrinsics
|
||||
"${cmd[@]}" --features arch,unstable-intrinsics --benches
|
||||
|
||||
# Test the same in release mode, which also increases coverage. Also ensure
|
||||
# the soft float routines are checked.
|
||||
"${cmd[@]}" "$profile_flag" release-checked
|
||||
"${cmd[@]}" "$profile_flag" release-checked --features force-soft-floats
|
||||
"${cmd[@]}" "$profile_flag" release-checked --features unstable-intrinsics
|
||||
"${cmd[@]}" "$profile_flag" release-checked --features unstable-intrinsics --benches
|
||||
"${cmd[@]}" "$profile_flag" release-checked --features arch
|
||||
"${cmd[@]}" "$profile_flag" release-checked --features arch,unstable-intrinsics
|
||||
"${cmd[@]}" "$profile_flag" release-checked --features arch,unstable-intrinsics --benches
|
||||
|
||||
# Ensure that the routines do not panic.
|
||||
#
|
||||
|
||||
@@ -34,27 +34,28 @@ core = { path = "../../core", optional = true }
|
||||
cc = { version = "1.2", optional = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
default = ["arch"]
|
||||
|
||||
# Enable architecture-specific features such as SIMD or assembly routines. If
|
||||
# disabled, the generic version can be tested on any platform.
|
||||
arch = []
|
||||
|
||||
# Enable compilation of C code in compiler-rt, filling in some more optimized
|
||||
# implementations and also filling in unimplemented intrinsics
|
||||
c = ["dep:cc"]
|
||||
|
||||
# For implementations where there is both a generic version and a platform-
|
||||
# specific version, use the generic version. This is meant to enable testing
|
||||
# the generic versions on all platforms.
|
||||
no-asm = []
|
||||
|
||||
# Flag this library as the unstable compiler-builtins lib. This must be enabled
|
||||
# when using as `std`'s dependency.'
|
||||
compiler-builtins = ["dep:core"]
|
||||
compiler-builtins = ["dep:core", "unmangled-names"]
|
||||
|
||||
# Generate memory-related intrinsics like memcpy
|
||||
# Enable `no_mangle` symbols for memory-related intrinsics like memcpy. The
|
||||
# mangled versions are always available.
|
||||
mem = []
|
||||
|
||||
# Mangle all names so this can be linked in with other versions or other
|
||||
# compiler-rt implementations. Also used for testing
|
||||
mangled-names = []
|
||||
# Enable `no_mangle` symbols so this crate gets used as the runtime intrinsic
|
||||
# implementation. Leave this disabled for testing to avoid conflicting with
|
||||
# the system intrinsics.
|
||||
unmangled-names = []
|
||||
|
||||
# This makes certain traits and function specializations public that
|
||||
# are not normally public but are required by the `builtins-test`
|
||||
|
||||
@@ -1,120 +1,85 @@
|
||||
#[path = "../libm/configure.rs"]
|
||||
mod configure;
|
||||
|
||||
use std::env;
|
||||
|
||||
use configure::{Target, configure_aliases};
|
||||
use configure::{Config, Library, set_cfg};
|
||||
|
||||
fn main() {
|
||||
println!("cargo::rerun-if-changed=build.rs");
|
||||
println!("cargo::rerun-if-changed=configure.rs");
|
||||
let cfg = Config::from_env(Library::CompilerBuiltins);
|
||||
let llvm_target = &cfg.target_triple_split;
|
||||
|
||||
let target = Target::from_env();
|
||||
let cwd = env::current_dir().unwrap();
|
||||
// Work around building as part of `builtins-shim`: if only `build.rs` is used, Cargo always
|
||||
// considers the build dirty because `builtins-shim/build.rs` does not exist. If only
|
||||
// `../c-b/build.rs` is used, the same may happen if not built in the workspace.
|
||||
if cfg.manifest_dir.file_name().unwrap() == "builtins-shim" {
|
||||
println!("cargo::rerun-if-changed=../compiler-builtins/build.rs");
|
||||
} else {
|
||||
println!("cargo::rerun-if-changed=build.rs");
|
||||
}
|
||||
|
||||
println!("cargo::rerun-if-changed=../libm/configure.rs");
|
||||
|
||||
configure::emit(&cfg);
|
||||
configure_check_cfg();
|
||||
configure_aliases(&target);
|
||||
|
||||
configure_libm(&target);
|
||||
|
||||
let cwd = env::current_dir().unwrap();
|
||||
println!("cargo:compiler-rt={}", cwd.join("compiler-rt").display());
|
||||
|
||||
println!("cargo::rustc-check-cfg=cfg(kernel_user_helpers)");
|
||||
println!("cargo::rustc-check-cfg=cfg(feature, values(\"mem-unaligned\"))");
|
||||
|
||||
// Emscripten's runtime includes all the builtins
|
||||
if target.os == "emscripten" {
|
||||
return;
|
||||
}
|
||||
|
||||
// OpenBSD provides compiler_rt by default, use it instead of rebuilding it from source
|
||||
if target.os == "openbsd" {
|
||||
println!("cargo:rustc-link-search=native=/usr/lib");
|
||||
println!("cargo:rustc-link-lib=compiler_rt");
|
||||
return;
|
||||
}
|
||||
|
||||
// Forcibly enable memory intrinsics on wasm & SGX as we don't have a libc to
|
||||
// provide them.
|
||||
if (target.triple.contains("wasm") && !target.triple.contains("wasi"))
|
||||
|| (target.triple.contains("sgx") && target.triple.contains("fortanix"))
|
||||
|| target.triple.contains("-none")
|
||||
|| target.triple.contains("nvptx")
|
||||
|| target.triple.contains("uefi")
|
||||
|| target.triple.contains("xous")
|
||||
if (cfg.target_triple.contains("wasm") && !cfg.target_triple.contains("wasi"))
|
||||
|| (cfg.target_triple.contains("sgx") && cfg.target_triple.contains("fortanix"))
|
||||
|| cfg.target_triple.contains("-none")
|
||||
|| cfg.target_triple.contains("nvptx")
|
||||
|| cfg.target_triple.contains("uefi")
|
||||
|| cfg.target_triple.contains("xous")
|
||||
{
|
||||
println!("cargo:rustc-cfg=feature=\"mem\"");
|
||||
}
|
||||
|
||||
// These targets have hardware unaligned access support.
|
||||
if target.arch.contains("x86_64")
|
||||
|| target.arch.contains("x86")
|
||||
|| target.arch.contains("aarch64")
|
||||
|| target.arch.contains("bpf")
|
||||
{
|
||||
println!("cargo:rustc-cfg=feature=\"mem-unaligned\"");
|
||||
let mem_unaligned = cfg.target_arch.contains("x86_64")
|
||||
|| cfg.target_arch.contains("x86")
|
||||
|| cfg.target_arch.contains("aarch64")
|
||||
|| cfg.target_arch.contains("bpf");
|
||||
set_cfg("mem_unaligned", mem_unaligned);
|
||||
|
||||
// Only emit the ARM Linux atomic emulation on pre-ARMv6 architectures. This
|
||||
// includes the old androideabi. It is deprecated but it is available as a
|
||||
// rustc target (arm-linux-androideabi).
|
||||
let kernel_user_helpers = llvm_target[0] == "armv4t"
|
||||
|| llvm_target[0] == "armv5te"
|
||||
|| cfg.target_triple == "arm-linux-androideabi";
|
||||
set_cfg("kernel_user_helpers", kernel_user_helpers);
|
||||
|
||||
let mut maybe_build_c = true;
|
||||
|
||||
// Emscripten's runtime includes all the builtins
|
||||
if cfg.target_os == "emscripten" {
|
||||
maybe_build_c = false;
|
||||
}
|
||||
|
||||
// NOTE we are going to assume that llvm-target, what determines our codegen option, matches the
|
||||
// target triple. This is usually correct for our built-in targets but can break in presence of
|
||||
// custom targets, which can have arbitrary names.
|
||||
let llvm_target = target.triple.split('-').collect::<Vec<_>>();
|
||||
// OpenBSD provides compiler_rt by default, use it instead of rebuilding it from source
|
||||
if cfg.target_os == "openbsd" {
|
||||
println!("cargo:rustc-link-search=native=/usr/lib");
|
||||
println!("cargo:rustc-link-lib=compiler_rt");
|
||||
maybe_build_c = false;
|
||||
}
|
||||
|
||||
// Everything is LLVM bitcode, not compatible with mixed C/Rust
|
||||
if cfg.target_arch.contains("nvptx") {
|
||||
maybe_build_c = false;
|
||||
}
|
||||
|
||||
// Build missing intrinsics from compiler-rt C source code. If we're
|
||||
// mangling names though we assume that we're also in test mode so we don't
|
||||
// build anything and we rely on the upstream implementation of compiler-rt
|
||||
// functions
|
||||
if !cfg!(feature = "mangled-names") && cfg!(feature = "c") {
|
||||
// Don't use a C compiler for these targets:
|
||||
//
|
||||
// * nvptx - everything is bitcode, not compatible with mixed C/Rust
|
||||
if !target.arch.contains("nvptx") {
|
||||
#[cfg(feature = "c")]
|
||||
c::compile(&llvm_target, &target);
|
||||
}
|
||||
if cfg!(feature = "unmangled-names") && cfg!(feature = "c") && maybe_build_c {
|
||||
#[cfg(feature = "c")]
|
||||
c::compile(&cfg);
|
||||
}
|
||||
|
||||
// Only emit the ARM Linux atomic emulation on pre-ARMv6 architectures. This
|
||||
// includes the old androideabi. It is deprecated but it is available as a
|
||||
// rustc target (arm-linux-androideabi).
|
||||
if llvm_target[0] == "armv4t"
|
||||
|| llvm_target[0] == "armv5te"
|
||||
|| target.triple == "arm-linux-androideabi"
|
||||
{
|
||||
println!("cargo:rustc-cfg=kernel_user_helpers")
|
||||
}
|
||||
}
|
||||
|
||||
/// Run configuration for `libm` since it is included directly.
|
||||
///
|
||||
/// Much of this is copied from `libm/configure.rs`.
|
||||
fn configure_libm(target: &Target) {
|
||||
println!("cargo:rustc-check-cfg=cfg(intrinsics_enabled)");
|
||||
println!("cargo:rustc-check-cfg=cfg(arch_enabled)");
|
||||
println!("cargo:rustc-check-cfg=cfg(optimizations_enabled)");
|
||||
println!("cargo:rustc-check-cfg=cfg(feature, values(\"unstable-public-internals\"))");
|
||||
|
||||
// Always use intrinsics
|
||||
println!("cargo:rustc-cfg=intrinsics_enabled");
|
||||
|
||||
// The arch module may contain assembly.
|
||||
if !cfg!(feature = "no-asm") {
|
||||
println!("cargo:rustc-cfg=arch_enabled");
|
||||
}
|
||||
|
||||
println!("cargo:rustc-check-cfg=cfg(optimizations_enabled)");
|
||||
if !matches!(target.opt_level.as_str(), "0" | "1") {
|
||||
println!("cargo:rustc-cfg=optimizations_enabled");
|
||||
}
|
||||
|
||||
println!(
|
||||
"cargo:rustc-env=CFG_CARGO_FEATURES={:?}",
|
||||
target.cargo_features
|
||||
);
|
||||
println!("cargo:rustc-env=CFG_OPT_LEVEL={}", target.opt_level);
|
||||
println!("cargo:rustc-env=CFG_TARGET_FEATURES={:?}", target.features);
|
||||
|
||||
// Activate libm's unstable features to make full use of Nightly.
|
||||
println!("cargo:rustc-cfg=feature=\"unstable-intrinsics\"");
|
||||
}
|
||||
|
||||
/// Emit directives for features we expect to support that aren't in `Cargo.toml`.
|
||||
@@ -176,10 +141,6 @@ fn configure_check_cfg() {
|
||||
// Rustc is unaware of sparc target features, but this does show up from
|
||||
// `rustc --print target-features --target sparc64-unknown-linux-gnu`.
|
||||
println!("cargo::rustc-check-cfg=cfg(target_feature, values(\"vis3\"))");
|
||||
|
||||
// FIXME: these come from libm and should be changed there
|
||||
println!("cargo::rustc-check-cfg=cfg(feature, values(\"checked\"))");
|
||||
println!("cargo::rustc-check-cfg=cfg(assert_no_panic)");
|
||||
}
|
||||
|
||||
#[cfg(feature = "c")]
|
||||
@@ -190,7 +151,7 @@ mod c {
|
||||
use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use super::Target;
|
||||
use super::Config;
|
||||
|
||||
struct Sources {
|
||||
// SYMBOL -> PATH TO SOURCE
|
||||
@@ -232,17 +193,18 @@ fn remove(&mut self, symbols: &[&str]) {
|
||||
}
|
||||
|
||||
/// Compile intrinsics from the compiler-rt C source code
|
||||
pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
pub fn compile(cfg: &Config) {
|
||||
let llvm_target = &cfg.target_triple_split;
|
||||
let mut consider_float_intrinsics = true;
|
||||
let cfg = &mut cc::Build::new();
|
||||
let build = &mut cc::Build::new();
|
||||
|
||||
// AArch64 GCCs exit with an error condition when they encounter any kind of floating point
|
||||
// code if the `nofp` and/or `nosimd` compiler flags have been set.
|
||||
//
|
||||
// Therefore, evaluate if those flags are present and set a boolean that causes any
|
||||
// compiler-rt intrinsics that contain floating point source to be excluded for this target.
|
||||
if target.arch == "aarch64" {
|
||||
let cflags_key = String::from("CFLAGS_") + &(target.triple.replace("-", "_"));
|
||||
if cfg.target_arch == "aarch64" {
|
||||
let cflags_key = String::from("CFLAGS_") + &(cfg.target_triple.replace("-", "_"));
|
||||
if let Ok(cflags_value) = env::var(cflags_key) {
|
||||
if cflags_value.contains("+nofp") || cflags_value.contains("+nosimd") {
|
||||
consider_float_intrinsics = false;
|
||||
@@ -256,22 +218,22 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
// support `_Float16` on all targets (whereas Rust does). However, define the macro
|
||||
// anyway to prevent issues like rust#118813 and rust#123885 silently reoccuring if more
|
||||
// `f16` intrinsics get accidentally added here in the future.
|
||||
cfg.define("COMPILER_RT_HAS_FLOAT16", None);
|
||||
build.define("COMPILER_RT_HAS_FLOAT16", None);
|
||||
|
||||
cfg.warnings(false);
|
||||
build.warnings(false);
|
||||
|
||||
if target.env == "msvc" {
|
||||
if cfg.target_env == "msvc" {
|
||||
// Don't pull in extra libraries on MSVC
|
||||
cfg.flag("/Zl");
|
||||
build.flag("/Zl");
|
||||
|
||||
// Emulate C99 and C++11's __func__ for MSVC prior to 2013 CTP
|
||||
cfg.define("__func__", Some("__FUNCTION__"));
|
||||
build.define("__func__", Some("__FUNCTION__"));
|
||||
} else {
|
||||
// Turn off various features of gcc and such, mostly copying
|
||||
// compiler-rt's build system already
|
||||
cfg.flag("-fno-builtin");
|
||||
cfg.flag("-fvisibility=hidden");
|
||||
cfg.flag("-ffreestanding");
|
||||
build.flag("-fno-builtin");
|
||||
build.flag("-fvisibility=hidden");
|
||||
build.flag("-ffreestanding");
|
||||
// Avoid the following warning appearing once **per file**:
|
||||
// clang: warning: optimization flag '-fomit-frame-pointer' is not supported for target 'armv7' [-Wignored-optimization-argument]
|
||||
//
|
||||
@@ -280,17 +242,17 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
// `check_cxx_compiler_flag(-fomit-frame-pointer COMPILER_RT_HAS_FOMIT_FRAME_POINTER_FLAG)`
|
||||
//
|
||||
// in https://github.com/rust-lang/compiler-rt/blob/c8fbcb3/cmake/config-ix.cmake#L19.
|
||||
cfg.flag_if_supported("-fomit-frame-pointer");
|
||||
cfg.define("VISIBILITY_HIDDEN", None);
|
||||
build.flag_if_supported("-fomit-frame-pointer");
|
||||
build.define("VISIBILITY_HIDDEN", None);
|
||||
|
||||
if let "aarch64" | "arm64ec" = target.arch.as_str() {
|
||||
if let "aarch64" | "arm64ec" = cfg.target_arch.as_str() {
|
||||
// FIXME(llvm20): Older GCCs on A64 fail to build with
|
||||
// -Werror=implicit-function-declaration due to a compiler-rt bug.
|
||||
// With a newer LLVM we should be able to enable the flag everywhere.
|
||||
// https://github.com/llvm/llvm-project/commit/8aa9d6206ce55bdaaf422839c351fbd63f033b89
|
||||
} else {
|
||||
// Avoid implicitly creating references to undefined functions
|
||||
cfg.flag("-Werror=implicit-function-declaration");
|
||||
build.flag("-Werror=implicit-function-declaration");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,14 +261,14 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
// at odds with compiling with `-ffreestanding`, as the header
|
||||
// may be incompatible or not present. Create a minimal stub
|
||||
// header to use instead.
|
||||
if target.os == "uefi" {
|
||||
if cfg.target_os == "uefi" {
|
||||
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
let include_dir = out_dir.join("include");
|
||||
if !include_dir.exists() {
|
||||
fs::create_dir(&include_dir).unwrap();
|
||||
}
|
||||
fs::write(include_dir.join("stdlib.h"), "#include <stddef.h>").unwrap();
|
||||
cfg.flag(&format!("-I{}", include_dir.to_str().unwrap()));
|
||||
build.flag(&format!("-I{}", include_dir.to_str().unwrap()));
|
||||
}
|
||||
|
||||
let mut sources = Sources::new();
|
||||
@@ -344,7 +306,7 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
|
||||
// On iOS and 32-bit OSX these are all just empty intrinsics, no need to
|
||||
// include them.
|
||||
if target.vendor != "apple" || target.arch != "x86" {
|
||||
if cfg.target_vendor != "apple" || cfg.target_arch != "x86" {
|
||||
sources.extend(&[
|
||||
("__absvti2", "absvti2.c"),
|
||||
("__addvti3", "addvti3.c"),
|
||||
@@ -363,7 +325,7 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
}
|
||||
}
|
||||
|
||||
if target.vendor == "apple" {
|
||||
if cfg.target_vendor == "apple" {
|
||||
sources.extend(&[
|
||||
("atomic_flag_clear", "atomic_flag_clear.c"),
|
||||
("atomic_flag_clear_explicit", "atomic_flag_clear_explicit.c"),
|
||||
@@ -377,8 +339,8 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
]);
|
||||
}
|
||||
|
||||
if target.env != "msvc" {
|
||||
if target.arch == "x86" {
|
||||
if cfg.target_env != "msvc" {
|
||||
if cfg.target_arch == "x86" {
|
||||
sources.extend(&[
|
||||
("__ashldi3", "i386/ashldi3.S"),
|
||||
("__ashrdi3", "i386/ashrdi3.S"),
|
||||
@@ -392,7 +354,7 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
}
|
||||
}
|
||||
|
||||
if target.arch == "arm" && target.vendor != "apple" && target.env != "msvc" {
|
||||
if cfg.target_arch == "arm" && cfg.target_vendor != "apple" && cfg.target_env != "msvc" {
|
||||
sources.extend(&[
|
||||
("__aeabi_div0", "arm/aeabi_div0.c"),
|
||||
("__aeabi_drsub", "arm/aeabi_drsub.c"),
|
||||
@@ -412,7 +374,7 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
("__umodsi3", "arm/umodsi3.S"),
|
||||
]);
|
||||
|
||||
if target.os == "freebsd" {
|
||||
if cfg.target_os == "freebsd" {
|
||||
sources.extend(&[("__clear_cache", "clear_cache.c")]);
|
||||
}
|
||||
|
||||
@@ -484,31 +446,36 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
]);
|
||||
}
|
||||
|
||||
if (target.arch == "aarch64" || target.arch == "arm64ec") && consider_float_intrinsics {
|
||||
if (cfg.target_arch == "aarch64" || cfg.target_arch == "arm64ec")
|
||||
&& consider_float_intrinsics
|
||||
{
|
||||
sources.extend(&[
|
||||
("__fe_getround", "fp_mode.c"),
|
||||
("__fe_raise_inexact", "fp_mode.c"),
|
||||
]);
|
||||
|
||||
if target.os != "windows" && target.os != "cygwin" {
|
||||
if cfg.target_os != "windows" && cfg.target_os != "cygwin" {
|
||||
sources.extend(&[("__multc3", "multc3.c")]);
|
||||
}
|
||||
}
|
||||
|
||||
if target.arch == "mips" || target.arch == "riscv32" || target.arch == "riscv64" {
|
||||
if cfg.target_arch == "mips" || cfg.target_arch == "riscv32" || cfg.target_arch == "riscv64"
|
||||
{
|
||||
sources.extend(&[("__bswapsi2", "bswapsi2.c")]);
|
||||
}
|
||||
|
||||
if target.arch == "mips64" {
|
||||
if cfg.target_arch == "mips64" {
|
||||
sources.extend(&[("__fe_getround", "fp_mode.c")]);
|
||||
}
|
||||
|
||||
if target.arch == "loongarch64" {
|
||||
if cfg.target_arch == "loongarch64" {
|
||||
sources.extend(&[("__fe_getround", "fp_mode.c")]);
|
||||
}
|
||||
|
||||
// Remove the assembly implementations that won't compile for the target
|
||||
if llvm_target[0] == "thumbv6m" || llvm_target[0] == "thumbv8m.base" || target.os == "uefi"
|
||||
if llvm_target[0] == "thumbv6m"
|
||||
|| llvm_target[0] == "thumbv8m.base"
|
||||
|| cfg.target_os == "uefi"
|
||||
{
|
||||
let mut to_remove = Vec::new();
|
||||
for (k, v) in sources.map.iter() {
|
||||
@@ -524,19 +491,19 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
}
|
||||
|
||||
// Android and Cygwin uses emulated TLS so we need a runtime support function.
|
||||
if target.os == "android" || target.os == "cygwin" {
|
||||
if cfg.target_os == "android" || cfg.target_os == "cygwin" {
|
||||
sources.extend(&[("__emutls_get_address", "emutls.c")]);
|
||||
}
|
||||
|
||||
// Work around a bug in the NDK headers (fixed in
|
||||
// https://r.android.com/2038949 which will be released in a future
|
||||
// NDK version) by providing a definition of LONG_BIT.
|
||||
if target.os == "android" {
|
||||
cfg.define("LONG_BIT", "(8 * sizeof(long))");
|
||||
if cfg.target_os == "android" {
|
||||
build.define("LONG_BIT", "(8 * sizeof(long))");
|
||||
}
|
||||
|
||||
// OpenHarmony also uses emulated TLS.
|
||||
if target.env == "ohos" {
|
||||
if cfg.target_env == "ohos" {
|
||||
sources.extend(&[("__emutls_get_address", "emutls.c")]);
|
||||
}
|
||||
|
||||
@@ -568,16 +535,16 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
// Support deterministic builds by remapping the __FILE__ prefix if the
|
||||
// compiler supports it. This fixes the nondeterminism caused by the
|
||||
// use of that macro in lib/builtins/int_util.h in compiler-rt.
|
||||
cfg.flag_if_supported(&format!("-ffile-prefix-map={}=.", root.display()));
|
||||
build.flag_if_supported(&format!("-ffile-prefix-map={}=.", root.display()));
|
||||
|
||||
// Include out-of-line atomics for aarch64, which are all generated by supplying different
|
||||
// sets of flags to the same source file.
|
||||
// Note: Out-of-line aarch64 atomics are not supported by the msvc toolchain (#430) and
|
||||
// on uefi.
|
||||
let src_dir = root.join("lib/builtins");
|
||||
if target.arch == "aarch64" && target.env != "msvc" && target.os != "uefi" {
|
||||
if cfg.target_arch == "aarch64" && cfg.target_env != "msvc" && cfg.target_os != "uefi" {
|
||||
// See below for why we're building these as separate libraries.
|
||||
build_aarch64_out_of_line_atomics_libraries(&src_dir, cfg, link_against_prebuilt_rt);
|
||||
build_aarch64_out_of_line_atomics_libraries(&src_dir, build, link_against_prebuilt_rt);
|
||||
|
||||
// Some run-time CPU feature detection is necessary, as well.
|
||||
let cpu_model_src = if src_dir.join("cpu_model.c").exists() {
|
||||
@@ -592,7 +559,7 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
for (sym, src) in sources.map.iter() {
|
||||
let src = src_dir.join(src);
|
||||
if !link_against_prebuilt_rt && added_sources.insert(src.clone()) {
|
||||
cfg.file(&src);
|
||||
build.file(&src);
|
||||
println!("cargo:rerun-if-changed={}", src.display());
|
||||
}
|
||||
println!("cargo:rustc-cfg={}=\"optimized-c\"", sym);
|
||||
@@ -616,7 +583,7 @@ pub fn compile(llvm_target: &[&str], target: &Target) {
|
||||
);
|
||||
}
|
||||
} else {
|
||||
cfg.compile("libcompiler-rt.a");
|
||||
build.compile("libcompiler-rt.a");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,107 +0,0 @@
|
||||
// Configuration that is shared between `compiler_builtins` and `builtins_test`.
|
||||
|
||||
use std::{env, str};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct Target {
|
||||
pub triple: String,
|
||||
pub triple_split: Vec<String>,
|
||||
pub opt_level: String,
|
||||
pub cargo_features: Vec<String>,
|
||||
pub os: String,
|
||||
pub arch: String,
|
||||
pub vendor: String,
|
||||
pub env: String,
|
||||
pub pointer_width: u8,
|
||||
pub little_endian: bool,
|
||||
pub features: Vec<String>,
|
||||
pub reliable_f128: bool,
|
||||
pub reliable_f16: bool,
|
||||
}
|
||||
|
||||
impl Target {
|
||||
pub fn from_env() -> Self {
|
||||
let triple = env::var("TARGET").unwrap();
|
||||
let triple_split = triple.split('-').map(ToOwned::to_owned).collect();
|
||||
let little_endian = match env::var("CARGO_CFG_TARGET_ENDIAN").unwrap().as_str() {
|
||||
"little" => true,
|
||||
"big" => false,
|
||||
x => panic!("unknown endian {x}"),
|
||||
};
|
||||
let cargo_features = env::vars()
|
||||
.filter_map(|(name, _value)| name.strip_prefix("CARGO_FEATURE_").map(ToOwned::to_owned))
|
||||
.map(|s| s.to_lowercase().replace("_", "-"))
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
triple,
|
||||
triple_split,
|
||||
os: env::var("CARGO_CFG_TARGET_OS").unwrap(),
|
||||
opt_level: env::var("OPT_LEVEL").unwrap(),
|
||||
cargo_features,
|
||||
arch: env::var("CARGO_CFG_TARGET_ARCH").unwrap(),
|
||||
vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
|
||||
env: env::var("CARGO_CFG_TARGET_ENV").unwrap(),
|
||||
pointer_width: env::var("CARGO_CFG_TARGET_POINTER_WIDTH")
|
||||
.unwrap()
|
||||
.parse()
|
||||
.unwrap(),
|
||||
little_endian,
|
||||
features: env::var("CARGO_CFG_TARGET_FEATURE")
|
||||
.unwrap_or_default()
|
||||
.split(",")
|
||||
.map(ToOwned::to_owned)
|
||||
.collect(),
|
||||
// Note that these are unstable options, so only show up with the nightly compiler or
|
||||
// with `RUSTC_BOOTSTRAP=1` (which is required to use the types anyway).
|
||||
reliable_f128: env::var_os("CARGO_CFG_TARGET_HAS_RELIABLE_F128").is_some(),
|
||||
reliable_f16: env::var_os("CARGO_CFG_TARGET_HAS_RELIABLE_F16").is_some(),
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub fn has_feature(&self, feature: &str) -> bool {
|
||||
self.features.iter().any(|f| f == feature)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn configure_aliases(target: &Target) {
|
||||
// To compile builtins-test-intrinsics for thumb targets, where there is no libc
|
||||
println!("cargo::rustc-check-cfg=cfg(thumb)");
|
||||
if target.triple_split[0].starts_with("thumb") {
|
||||
println!("cargo:rustc-cfg=thumb")
|
||||
}
|
||||
|
||||
// compiler-rt `cfg`s away some intrinsics for thumbv6m and thumbv8m.base because
|
||||
// these targets do not have full Thumb-2 support but only original Thumb-1.
|
||||
// We have to cfg our code accordingly.
|
||||
println!("cargo::rustc-check-cfg=cfg(thumb_1)");
|
||||
if target.triple_split[0] == "thumbv6m" || target.triple_split[0] == "thumbv8m.base" {
|
||||
println!("cargo:rustc-cfg=thumb_1")
|
||||
}
|
||||
|
||||
// Config shorthands
|
||||
println!("cargo:rustc-check-cfg=cfg(x86_no_sse)");
|
||||
if target.arch == "x86" && !target.features.iter().any(|f| f == "sse") {
|
||||
// Shorthand to detect i586 targets
|
||||
println!("cargo:rustc-cfg=x86_no_sse");
|
||||
}
|
||||
|
||||
/* Not all backends support `f16` and `f128` to the same level on all architectures, so we
|
||||
* need to disable things if the compiler may crash. See configuration at:
|
||||
* * https://github.com/rust-lang/rust/blob/c65dccabacdfd6c8a7f7439eba13422fdd89b91e/compiler/rustc_codegen_llvm/src/llvm_util.rs#L367-L432
|
||||
* * https://github.com/rust-lang/rustc_codegen_gcc/blob/4b5c44b14166083eef8d71f15f5ea1f53fc976a0/src/lib.rs#L496-L507
|
||||
* * https://github.com/rust-lang/rustc_codegen_cranelift/blob/c713ffab3c6e28ab4b4dd4e392330f786ea657ad/src/lib.rs#L196-L226
|
||||
*/
|
||||
|
||||
println!("cargo::rustc-check-cfg=cfg(f16_enabled)");
|
||||
if target.reliable_f16 {
|
||||
println!("cargo::rustc-cfg=f16_enabled");
|
||||
}
|
||||
|
||||
println!("cargo::rustc-check-cfg=cfg(f128_enabled)");
|
||||
if target.reliable_f128 {
|
||||
println!("cargo::rustc-cfg=f128_enabled");
|
||||
}
|
||||
}
|
||||
@@ -35,14 +35,14 @@ pub extern "C" fn __rust_enable_lse() {
|
||||
}
|
||||
|
||||
/// Function to enable/disable LSE. To be used only for testing purposes.
|
||||
#[cfg(feature = "mangled-names")]
|
||||
#[cfg(feature = "unstable-public-internals")]
|
||||
pub unsafe fn set_have_lse_atomics(has_lse: bool) {
|
||||
let lse_flag = if has_lse { 1 } else { 0 };
|
||||
HAVE_LSE_ATOMICS.store(lse_flag, Ordering::Relaxed);
|
||||
}
|
||||
|
||||
/// Function to obtain whether LSE is enabled or not. To be used only for testing purposes.
|
||||
#[cfg(feature = "mangled-names")]
|
||||
#[cfg(feature = "unstable-public-internals")]
|
||||
pub fn get_have_lse_atomics() -> bool {
|
||||
HAVE_LSE_ATOMICS.load(Ordering::Relaxed) != 0
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::float::Float;
|
||||
use crate::int::{CastFrom, CastInto, Int, MinInt};
|
||||
use crate::support::{CastFrom, CastInto, Float, Int, MinInt};
|
||||
|
||||
/// Returns `a + b`
|
||||
fn add<F: Float>(a: F, b: F) -> F
|
||||
|
||||
@@ -1,21 +1,28 @@
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
use crate::float::Float;
|
||||
use crate::int::MinInt;
|
||||
use crate::support::cfg_if;
|
||||
use crate::support::{Float, MinInt, cfg_if};
|
||||
|
||||
// Taken from LLVM config:
|
||||
// https://github.com/llvm/llvm-project/blob/0cf3c437c18ed27d9663d87804a9a15ff6874af2/compiler-rt/lib/builtins/fp_compare_impl.inc#L11-L27
|
||||
// These definitions should be consistent with LLVM's definition from `getCmpLibcallReturnType`,
|
||||
// compiler-rt's definitions [1], GCC's `CMPtype` [2], and `libgcc`. To find the definitions
|
||||
// in GCC, there are a few things to grep for:
|
||||
//
|
||||
// * `default_libgcc_cmp_return_mode` for the default (word sized)
|
||||
// * `TARGET_LIBGCC_CMP_RETURN_MODE` for the target hook to override the default
|
||||
// * `# *define *CMPtype` as a last resort, for overrides that don't use the hook (AVR)
|
||||
//
|
||||
// [1]: https://github.com/llvm/llvm-project/blob/0cf3c437c18ed27d9663d87804a9a15ff6874af2/compiler-rt/lib/builtins/fp_compare_impl.inc#L11-L27
|
||||
// [2]: https://gcc.gnu.org/onlinedocs/gccint/Soft-float-library-routines.html#Comparison-functions-1
|
||||
cfg_if! {
|
||||
if #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))] {
|
||||
if #[cfg(any(target_arch = "aarch64", target_arch = "arm64ec", target_family = "wasm"))] {
|
||||
// Aarch64 uses `int` rather than a pointer-sized value.
|
||||
// `getCmpLibcallReturnType` for WASM is always set to i32.
|
||||
pub type CmpResult = i32;
|
||||
} else if #[cfg(target_arch = "avr")] {
|
||||
// AVR uses a single byte.
|
||||
pub type CmpResult = i8;
|
||||
} else {
|
||||
// In compiler-rt, LLP64 ABIs use `long long` and everything else uses `long`. In effect,
|
||||
// this means the return value is always pointer-sized.
|
||||
// The default is word-sized. In LLVM's compiler-rt, this is done by using `long long` on
|
||||
// LLP64 ABIs and `long` on everything else.
|
||||
pub type CmpResult = isize;
|
||||
}
|
||||
}
|
||||
@@ -28,8 +35,18 @@ enum Result {
|
||||
Unordered,
|
||||
}
|
||||
|
||||
/// Conversions to match GCC intrinsics [1].
|
||||
///
|
||||
/// * `unord`: nonzero if either NaN, 0 otherwise
|
||||
/// * `eq`, `ne`: 0 if a == b and both YaN, nonzero otherwise
|
||||
/// * `ge`, `gt`, `lt`, `le`: return an int result that provides the same comparison to 0 if both
|
||||
/// YaN and the comparison matches. E.g. if a >= b, `ge` returns an `x >= 0`.
|
||||
///
|
||||
/// The separate map functions are only needed to handle the unordered case.
|
||||
///
|
||||
/// [1]: https://gcc.gnu.org/onlinedocs/gccint/Soft-float-library-routines.html#Comparison-functions-1
|
||||
impl Result {
|
||||
fn to_le_abi(self) -> CmpResult {
|
||||
fn to_default_cmp_result(self) -> CmpResult {
|
||||
match self {
|
||||
Result::Less => -1,
|
||||
Result::Equal => 0,
|
||||
@@ -38,7 +55,7 @@ fn to_le_abi(self) -> CmpResult {
|
||||
}
|
||||
}
|
||||
|
||||
fn to_ge_abi(self) -> CmpResult {
|
||||
fn to_gt_ge_cmp_result(self) -> CmpResult {
|
||||
match self {
|
||||
Result::Less => -1,
|
||||
Result::Equal => 0,
|
||||
@@ -118,11 +135,11 @@ fn unord<F: Float>(a: F, b: F) -> bool {
|
||||
#[cfg(f16_enabled)]
|
||||
intrinsics! {
|
||||
pub extern "C" fn __lehf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __gehf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_ge_abi()
|
||||
cmp(a, b).to_gt_ge_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __unordhf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
|
||||
@@ -130,29 +147,29 @@ pub extern "C" fn __unordhf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
|
||||
}
|
||||
|
||||
pub extern "C" fn __eqhf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __lthf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __nehf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __gthf2(a: f16, b: f16) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_ge_abi()
|
||||
cmp(a, b).to_gt_ge_cmp_result()
|
||||
}
|
||||
}
|
||||
|
||||
intrinsics! {
|
||||
pub extern "C" fn __lesf2(a: f32, b: f32) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __gesf2(a: f32, b: f32) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_ge_abi()
|
||||
cmp(a, b).to_gt_ge_cmp_result()
|
||||
}
|
||||
|
||||
#[arm_aeabi_alias = __aeabi_fcmpun]
|
||||
@@ -161,27 +178,27 @@ pub extern "C" fn __unordsf2(a: f32, b: f32) -> crate::float::cmp::CmpResult {
|
||||
}
|
||||
|
||||
pub extern "C" fn __eqsf2(a: f32, b: f32) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __ltsf2(a: f32, b: f32) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __nesf2(a: f32, b: f32) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __gtsf2(a: f32, b: f32) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_ge_abi()
|
||||
cmp(a, b).to_gt_ge_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __ledf2(a: f64, b: f64) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __gedf2(a: f64, b: f64) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_ge_abi()
|
||||
cmp(a, b).to_gt_ge_cmp_result()
|
||||
}
|
||||
|
||||
#[arm_aeabi_alias = __aeabi_dcmpun]
|
||||
@@ -190,19 +207,19 @@ pub extern "C" fn __unorddf2(a: f64, b: f64) -> crate::float::cmp::CmpResult {
|
||||
}
|
||||
|
||||
pub extern "C" fn __eqdf2(a: f64, b: f64) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __ltdf2(a: f64, b: f64) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __nedf2(a: f64, b: f64) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
pub extern "C" fn __gtdf2(a: f64, b: f64) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_ge_abi()
|
||||
cmp(a, b).to_gt_ge_cmp_result()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,12 +227,12 @@ pub extern "C" fn __gtdf2(a: f64, b: f64) -> crate::float::cmp::CmpResult {
|
||||
intrinsics! {
|
||||
#[ppc_alias = __lekf2]
|
||||
pub extern "C" fn __letf2(a: f128, b: f128) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
#[ppc_alias = __gekf2]
|
||||
pub extern "C" fn __getf2(a: f128, b: f128) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_ge_abi()
|
||||
cmp(a, b).to_gt_ge_cmp_result()
|
||||
}
|
||||
|
||||
#[ppc_alias = __unordkf2]
|
||||
@@ -225,22 +242,22 @@ pub extern "C" fn __unordtf2(a: f128, b: f128) -> crate::float::cmp::CmpResult {
|
||||
|
||||
#[ppc_alias = __eqkf2]
|
||||
pub extern "C" fn __eqtf2(a: f128, b: f128) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
#[ppc_alias = __ltkf2]
|
||||
pub extern "C" fn __lttf2(a: f128, b: f128) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
#[ppc_alias = __nekf2]
|
||||
pub extern "C" fn __netf2(a: f128, b: f128) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_le_abi()
|
||||
cmp(a, b).to_default_cmp_result()
|
||||
}
|
||||
|
||||
#[ppc_alias = __gtkf2]
|
||||
pub extern "C" fn __gttf2(a: f128, b: f128) -> crate::float::cmp::CmpResult {
|
||||
cmp(a, b).to_ge_abi()
|
||||
cmp(a, b).to_gt_ge_cmp_result()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use core::ops::Neg;
|
||||
|
||||
use super::Float;
|
||||
use crate::int::{CastFrom, CastInto, Int, MinInt};
|
||||
use crate::support::{CastFrom, CastInto, Float, Int, MinInt};
|
||||
|
||||
/// Conversions from integers to floats.
|
||||
///
|
||||
|
||||
@@ -82,9 +82,7 @@
|
||||
use core::mem::size_of;
|
||||
use core::ops;
|
||||
|
||||
use super::HalfRep;
|
||||
use crate::float::Float;
|
||||
use crate::int::{CastFrom, CastInto, DInt, HInt, Int, MinInt};
|
||||
use crate::support::{CastFrom, CastInto, DInt, Float, HInt, HalfRep, Int, MinInt};
|
||||
|
||||
fn div<F: Float>(a: F, b: F) -> F
|
||||
where
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::float::Float;
|
||||
use crate::int::{CastInto, Int, MinInt};
|
||||
use crate::support::{CastInto, Float, Int, MinInt};
|
||||
|
||||
/// Generic conversion from a narrower to a wider IEEE-754 floating-point type
|
||||
fn extend<F: Float, R: Float>(a: F) -> R
|
||||
|
||||
@@ -6,10 +6,4 @@
|
||||
pub mod mul;
|
||||
pub mod pow;
|
||||
pub mod sub;
|
||||
pub(crate) mod traits;
|
||||
pub mod trunc;
|
||||
|
||||
#[cfg(not(feature = "unstable-public-internals"))]
|
||||
pub(crate) use traits::{Float, HalfRep};
|
||||
#[cfg(feature = "unstable-public-internals")]
|
||||
pub use traits::{Float, HalfRep};
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::float::Float;
|
||||
use crate::int::{CastInto, DInt, HInt, Int, MinInt};
|
||||
use crate::support::{CastInto, DInt, Float, HInt, Int, MinInt};
|
||||
|
||||
fn mul<F: Float>(a: F, b: F) -> F
|
||||
where
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::float::Float;
|
||||
use crate::int::Int;
|
||||
use crate::support::{Float, Int};
|
||||
|
||||
/// Returns `a` raised to the power `b`
|
||||
fn pow<F: Float>(a: F, b: i32) -> F {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::float::Float;
|
||||
use crate::support::Float;
|
||||
|
||||
intrinsics! {
|
||||
#[cfg(f16_enabled)]
|
||||
|
||||
@@ -1,189 +0,0 @@
|
||||
use core::ops;
|
||||
|
||||
use crate::int::{DInt, Int, MinInt};
|
||||
|
||||
/// Wrapper to extract the integer type half of the float's size
|
||||
pub type HalfRep<F> = <<F as Float>::Int as DInt>::H;
|
||||
|
||||
/// Trait for some basic operations on floats
|
||||
#[allow(dead_code)]
|
||||
pub trait Float:
|
||||
Copy
|
||||
+ core::fmt::Debug
|
||||
+ PartialEq
|
||||
+ PartialOrd
|
||||
+ ops::AddAssign
|
||||
+ ops::MulAssign
|
||||
+ ops::Add<Output = Self>
|
||||
+ ops::Sub<Output = Self>
|
||||
+ ops::Div<Output = Self>
|
||||
+ ops::Rem<Output = Self>
|
||||
{
|
||||
/// A uint of the same width as the float
|
||||
type Int: Int<OtherSign = Self::SignedInt, Unsigned = Self::Int>;
|
||||
|
||||
/// A int of the same width as the float
|
||||
type SignedInt: Int + MinInt<OtherSign = Self::Int, Unsigned = Self::Int>;
|
||||
|
||||
/// An int capable of containing the exponent bits plus a sign bit. This is signed.
|
||||
type ExpInt: Int;
|
||||
|
||||
const ZERO: Self;
|
||||
const ONE: Self;
|
||||
|
||||
/// The bitwidth of the float type.
|
||||
const BITS: u32;
|
||||
|
||||
/// The bitwidth of the significand.
|
||||
const SIG_BITS: u32;
|
||||
|
||||
/// The bitwidth of the exponent.
|
||||
const EXP_BITS: u32 = Self::BITS - Self::SIG_BITS - 1;
|
||||
|
||||
/// The saturated (maximum bitpattern) value of the exponent, i.e. the infinite
|
||||
/// representation.
|
||||
///
|
||||
/// This is in the rightmost position, use `EXP_MASK` for the shifted value.
|
||||
const EXP_SAT: u32 = (1 << Self::EXP_BITS) - 1;
|
||||
|
||||
/// The exponent bias value.
|
||||
const EXP_BIAS: u32 = Self::EXP_SAT >> 1;
|
||||
|
||||
/// A mask for the sign bit.
|
||||
const SIGN_MASK: Self::Int;
|
||||
|
||||
/// A mask for the significand.
|
||||
const SIG_MASK: Self::Int;
|
||||
|
||||
/// The implicit bit of the float format.
|
||||
const IMPLICIT_BIT: Self::Int;
|
||||
|
||||
/// A mask for the exponent.
|
||||
const EXP_MASK: Self::Int;
|
||||
|
||||
/// Returns `self` transmuted to `Self::Int`
|
||||
fn to_bits(self) -> Self::Int;
|
||||
|
||||
/// Returns `self` transmuted to `Self::SignedInt`
|
||||
fn to_bits_signed(self) -> Self::SignedInt;
|
||||
|
||||
/// Checks if two floats have the same bit representation. *Except* for NaNs! NaN can be
|
||||
/// represented in multiple different ways. This method returns `true` if two NaNs are
|
||||
/// compared.
|
||||
fn eq_repr(self, rhs: Self) -> bool;
|
||||
|
||||
/// Returns true if the sign is negative
|
||||
fn is_sign_negative(self) -> bool;
|
||||
|
||||
/// Returns the exponent, not adjusting for bias.
|
||||
fn exp(self) -> Self::ExpInt;
|
||||
|
||||
/// Returns the significand with no implicit bit (or the "fractional" part)
|
||||
fn frac(self) -> Self::Int;
|
||||
|
||||
/// Returns the significand with implicit bit
|
||||
fn imp_frac(self) -> Self::Int;
|
||||
|
||||
/// Returns a `Self::Int` transmuted back to `Self`
|
||||
fn from_bits(a: Self::Int) -> Self;
|
||||
|
||||
/// Constructs a `Self` from its parts. Inputs are treated as bits and shifted into position.
|
||||
fn from_parts(negative: bool, exponent: Self::Int, significand: Self::Int) -> Self;
|
||||
|
||||
fn abs(self) -> Self {
|
||||
let abs_mask = !Self::SIGN_MASK;
|
||||
Self::from_bits(self.to_bits() & abs_mask)
|
||||
}
|
||||
|
||||
/// Returns (normalized exponent, normalized significand)
|
||||
fn normalize(significand: Self::Int) -> (i32, Self::Int);
|
||||
|
||||
/// Returns if `self` is subnormal
|
||||
fn is_subnormal(self) -> bool;
|
||||
}
|
||||
|
||||
macro_rules! float_impl {
|
||||
($ty:ident, $ity:ident, $sity:ident, $expty:ident, $bits:expr, $significand_bits:expr) => {
|
||||
impl Float for $ty {
|
||||
type Int = $ity;
|
||||
type SignedInt = $sity;
|
||||
type ExpInt = $expty;
|
||||
|
||||
const ZERO: Self = 0.0;
|
||||
const ONE: Self = 1.0;
|
||||
|
||||
const BITS: u32 = $bits;
|
||||
const SIG_BITS: u32 = $significand_bits;
|
||||
|
||||
const SIGN_MASK: Self::Int = 1 << (Self::BITS - 1);
|
||||
const SIG_MASK: Self::Int = (1 << Self::SIG_BITS) - 1;
|
||||
const IMPLICIT_BIT: Self::Int = 1 << Self::SIG_BITS;
|
||||
const EXP_MASK: Self::Int = !(Self::SIGN_MASK | Self::SIG_MASK);
|
||||
|
||||
fn to_bits(self) -> Self::Int {
|
||||
self.to_bits()
|
||||
}
|
||||
fn to_bits_signed(self) -> Self::SignedInt {
|
||||
self.to_bits() as Self::SignedInt
|
||||
}
|
||||
fn eq_repr(self, rhs: Self) -> bool {
|
||||
#[cfg(feature = "mangled-names")]
|
||||
fn is_nan(x: $ty) -> bool {
|
||||
// When using mangled-names, the "real" compiler-builtins might not have the
|
||||
// necessary builtin (__unordtf2) to test whether `f128` is NaN.
|
||||
// FIXME(f16_f128): Remove once the nightly toolchain has the __unordtf2 builtin
|
||||
// x is NaN if all the bits of the exponent are set and the significand is non-0
|
||||
x.to_bits() & $ty::EXP_MASK == $ty::EXP_MASK && x.to_bits() & $ty::SIG_MASK != 0
|
||||
}
|
||||
#[cfg(not(feature = "mangled-names"))]
|
||||
fn is_nan(x: $ty) -> bool {
|
||||
x.is_nan()
|
||||
}
|
||||
if is_nan(self) && is_nan(rhs) {
|
||||
true
|
||||
} else {
|
||||
self.to_bits() == rhs.to_bits()
|
||||
}
|
||||
}
|
||||
fn is_sign_negative(self) -> bool {
|
||||
self.is_sign_negative()
|
||||
}
|
||||
fn exp(self) -> Self::ExpInt {
|
||||
((self.to_bits() & Self::EXP_MASK) >> Self::SIG_BITS) as Self::ExpInt
|
||||
}
|
||||
fn frac(self) -> Self::Int {
|
||||
self.to_bits() & Self::SIG_MASK
|
||||
}
|
||||
fn imp_frac(self) -> Self::Int {
|
||||
self.frac() | Self::IMPLICIT_BIT
|
||||
}
|
||||
fn from_bits(a: Self::Int) -> Self {
|
||||
Self::from_bits(a)
|
||||
}
|
||||
fn from_parts(negative: bool, exponent: Self::Int, significand: Self::Int) -> Self {
|
||||
Self::from_bits(
|
||||
((negative as Self::Int) << (Self::BITS - 1))
|
||||
| ((exponent << Self::SIG_BITS) & Self::EXP_MASK)
|
||||
| (significand & Self::SIG_MASK),
|
||||
)
|
||||
}
|
||||
fn normalize(significand: Self::Int) -> (i32, Self::Int) {
|
||||
let shift = significand.leading_zeros().wrapping_sub(Self::EXP_BITS);
|
||||
(
|
||||
1i32.wrapping_sub(shift as i32),
|
||||
significand << shift as Self::Int,
|
||||
)
|
||||
}
|
||||
fn is_subnormal(self) -> bool {
|
||||
(self.to_bits() & Self::EXP_MASK) == Self::Int::ZERO
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(f16_enabled)]
|
||||
float_impl!(f16, u16, i16, i8, 16, 10);
|
||||
float_impl!(f32, u32, i32, i16, 32, 23);
|
||||
float_impl!(f64, u64, i64, i16, 64, 52);
|
||||
#[cfg(f128_enabled)]
|
||||
float_impl!(f128, u128, i128, i16, 128, 112);
|
||||
@@ -1,5 +1,4 @@
|
||||
use crate::float::Float;
|
||||
use crate::int::{CastInto, Int, MinInt};
|
||||
use crate::support::{CastInto, Float, Int, MinInt};
|
||||
|
||||
fn trunc<F: Float, R: Float>(a: F) -> R
|
||||
where
|
||||
|
||||
@@ -1,7 +1,66 @@
|
||||
use core::arch::global_asm;
|
||||
|
||||
// Hexagon L1 cache line size in bytes (Hexagon PRM sections 5.10.3-5.10.4).
|
||||
const CACHE_LINE_SIZE: usize = 32;
|
||||
|
||||
intrinsics! {
|
||||
pub unsafe extern "C" fn __clear_cache(start: *mut u8, end: *mut u8) {
|
||||
// Hexagon has separate instruction and data caches.
|
||||
let mask = !(CACHE_LINE_SIZE - 1);
|
||||
let start_line = start.addr() & mask;
|
||||
let end_addr = end.addr();
|
||||
|
||||
// Clean and invalidate data cache to push new code to memory and
|
||||
// invalidate stale lines in the L2 cache.
|
||||
let mut addr = start_line;
|
||||
while addr < end_addr {
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"dccleaninva({addr})",
|
||||
addr = in(reg) addr,
|
||||
options(nostack, preserves_flags),
|
||||
);
|
||||
}
|
||||
addr += CACHE_LINE_SIZE;
|
||||
}
|
||||
|
||||
// Invalidate instruction cache so it re-fetches from memory.
|
||||
addr = start_line;
|
||||
while addr < end_addr {
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"icinva({addr})",
|
||||
addr = in(reg) addr,
|
||||
options(nostack, preserves_flags),
|
||||
);
|
||||
}
|
||||
addr += CACHE_LINE_SIZE;
|
||||
}
|
||||
|
||||
// Instruction sync barrier ensures subsequent fetches see the new code.
|
||||
unsafe {
|
||||
core::arch::asm!("isync", options(nostack, preserves_flags));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
global_asm!(include_str!("hexagon/func_macro.s"), options(raw));
|
||||
|
||||
global_asm!(
|
||||
include_str!("hexagon/common_entry_exit_abi1.s"),
|
||||
options(raw)
|
||||
);
|
||||
|
||||
global_asm!(
|
||||
include_str!("hexagon/common_entry_exit_abi2.s"),
|
||||
options(raw)
|
||||
);
|
||||
|
||||
global_asm!(
|
||||
include_str!("hexagon/common_entry_exit_legacy.s"),
|
||||
options(raw)
|
||||
);
|
||||
|
||||
global_asm!(include_str!("hexagon/dfaddsub.s"), options(raw));
|
||||
|
||||
global_asm!(include_str!("hexagon/dfdiv.s"), options(raw));
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
FUNCTION_BEGIN __save_r24_through_r27
|
||||
memd(fp+#-16) = r27:26
|
||||
FALLTHROUGH_TAIL_CALL __save_r24_through_r27 __save_r24_through_r25
|
||||
{
|
||||
memd(fp+#-8) = r25:24
|
||||
jumpr lr
|
||||
}
|
||||
FUNCTION_END __save_r24_through_r25
|
||||
|
||||
|
||||
FUNCTION_BEGIN __restore_r24_through_r27_and_deallocframe_before_tailcall
|
||||
r27:26 = memd(fp+#-16)
|
||||
FALLTHROUGH_TAIL_CALL __restore_r24_through_r27_and_deallocframe_before_tailcall __restore_r24_through_r25_and_deallocframe_before_tailcall
|
||||
{
|
||||
r25:24 = memd(fp+#-8)
|
||||
deallocframe
|
||||
jumpr lr
|
||||
}
|
||||
FUNCTION_END __restore_r24_through_r25_and_deallocframe_before_tailcall
|
||||
|
||||
|
||||
FUNCTION_BEGIN __restore_r24_through_r27_and_deallocframe
|
||||
{
|
||||
lr = memw(fp+#4)
|
||||
r27:26 = memd(fp+#-16)
|
||||
}
|
||||
{
|
||||
r25:24 = memd(fp+#-8)
|
||||
deallocframe
|
||||
jumpr lr
|
||||
}
|
||||
FUNCTION_END __restore_r24_through_r27_and_deallocframe
|
||||
|
||||
|
||||
FUNCTION_BEGIN __restore_r24_through_r25_and_deallocframe
|
||||
{
|
||||
r25:24 = memd(fp+#-8)
|
||||
deallocframe
|
||||
}
|
||||
jumpr lr
|
||||
FUNCTION_END __restore_r24_through_r25_and_deallocframe
|
||||
@@ -0,0 +1,237 @@
|
||||
|
||||
.macro ABI2_FUNCTION_BEGIN name
|
||||
.p2align 2
|
||||
.section .text.\name,"ax",@progbits
|
||||
.globl \name
|
||||
.type \name, @function
|
||||
\name:
|
||||
.endm
|
||||
|
||||
.macro ABI2_FUNCTION_END name
|
||||
.size \name, . - \name
|
||||
.endm
|
||||
|
||||
|
||||
ABI2_FUNCTION_BEGIN __save_r16_through_r27
|
||||
{
|
||||
memd(fp+#-48) = r27:26
|
||||
memd(fp+#-40) = r25:24
|
||||
}
|
||||
{
|
||||
memd(fp+#-32) = r23:22
|
||||
memd(fp+#-24) = r21:20
|
||||
}
|
||||
{
|
||||
memd(fp+#-16) = r19:18
|
||||
memd(fp+#-8) = r17:16
|
||||
jumpr lr
|
||||
}
|
||||
ABI2_FUNCTION_END __save_r16_through_r27
|
||||
|
||||
ABI2_FUNCTION_BEGIN __save_r16_through_r25
|
||||
{
|
||||
memd(fp+#-40) = r25:24
|
||||
memd(fp+#-32) = r23:22
|
||||
}
|
||||
{
|
||||
memd(fp+#-24) = r21:20
|
||||
memd(fp+#-16) = r19:18
|
||||
}
|
||||
{
|
||||
memd(fp+#-8) = r17:16
|
||||
jumpr lr
|
||||
}
|
||||
ABI2_FUNCTION_END __save_r16_through_r25
|
||||
|
||||
ABI2_FUNCTION_BEGIN __save_r16_through_r23
|
||||
{
|
||||
memd(fp+#-32) = r23:22
|
||||
memd(fp+#-24) = r21:20
|
||||
}
|
||||
{
|
||||
memd(fp+#-16) = r19:18
|
||||
memd(fp+#-8) = r17:16
|
||||
jumpr lr
|
||||
}
|
||||
ABI2_FUNCTION_END __save_r16_through_r23
|
||||
|
||||
ABI2_FUNCTION_BEGIN __save_r16_through_r21
|
||||
{
|
||||
memd(fp+#-24) = r21:20
|
||||
memd(fp+#-16) = r19:18
|
||||
}
|
||||
{
|
||||
memd(fp+#-8) = r17:16
|
||||
jumpr lr
|
||||
}
|
||||
ABI2_FUNCTION_END __save_r16_through_r21
|
||||
|
||||
ABI2_FUNCTION_BEGIN __save_r16_through_r19
|
||||
{
|
||||
memd(fp+#-16) = r19:18
|
||||
memd(fp+#-8) = r17:16
|
||||
jumpr lr
|
||||
}
|
||||
ABI2_FUNCTION_END __save_r16_through_r19
|
||||
|
||||
ABI2_FUNCTION_BEGIN __save_r16_through_r17
|
||||
{
|
||||
memd(fp+#-8) = r17:16
|
||||
jumpr lr
|
||||
}
|
||||
ABI2_FUNCTION_END __save_r16_through_r17
|
||||
|
||||
|
||||
ABI2_FUNCTION_BEGIN __restore_r16_through_r27_and_deallocframe_before_tailcall
|
||||
r27:26 = memd(fp+#-48)
|
||||
{
|
||||
r25:24 = memd(fp+#-40)
|
||||
r23:22 = memd(fp+#-32)
|
||||
}
|
||||
{
|
||||
r21:20 = memd(fp+#-24)
|
||||
r19:18 = memd(fp+#-16)
|
||||
}
|
||||
{
|
||||
r17:16 = memd(fp+#-8)
|
||||
deallocframe
|
||||
jumpr lr
|
||||
}
|
||||
ABI2_FUNCTION_END __restore_r16_through_r27_and_deallocframe_before_tailcall
|
||||
|
||||
ABI2_FUNCTION_BEGIN __restore_r16_through_r25_and_deallocframe_before_tailcall
|
||||
{
|
||||
r25:24 = memd(fp+#-40)
|
||||
r23:22 = memd(fp+#-32)
|
||||
}
|
||||
{
|
||||
r21:20 = memd(fp+#-24)
|
||||
r19:18 = memd(fp+#-16)
|
||||
}
|
||||
{
|
||||
r17:16 = memd(fp+#-8)
|
||||
deallocframe
|
||||
jumpr lr
|
||||
}
|
||||
ABI2_FUNCTION_END __restore_r16_through_r25_and_deallocframe_before_tailcall
|
||||
|
||||
ABI2_FUNCTION_BEGIN __restore_r16_through_r23_and_deallocframe_before_tailcall
|
||||
{
|
||||
r23:22 = memd(fp+#-32)
|
||||
r21:20 = memd(fp+#-24)
|
||||
}
|
||||
r19:18 = memd(fp+#-16)
|
||||
{
|
||||
r17:16 = memd(fp+#-8)
|
||||
deallocframe
|
||||
jumpr lr
|
||||
}
|
||||
ABI2_FUNCTION_END __restore_r16_through_r23_and_deallocframe_before_tailcall
|
||||
|
||||
|
||||
ABI2_FUNCTION_BEGIN __restore_r16_through_r21_and_deallocframe_before_tailcall
|
||||
{
|
||||
r21:20 = memd(fp+#-24)
|
||||
r19:18 = memd(fp+#-16)
|
||||
}
|
||||
{
|
||||
r17:16 = memd(fp+#-8)
|
||||
deallocframe
|
||||
jumpr lr
|
||||
}
|
||||
ABI2_FUNCTION_END __restore_r16_through_r21_and_deallocframe_before_tailcall
|
||||
|
||||
ABI2_FUNCTION_BEGIN __restore_r16_through_r19_and_deallocframe_before_tailcall
|
||||
r19:18 = memd(fp+#-16)
|
||||
{
|
||||
r17:16 = memd(fp+#-8)
|
||||
deallocframe
|
||||
jumpr lr
|
||||
}
|
||||
ABI2_FUNCTION_END __restore_r16_through_r19_and_deallocframe_before_tailcall
|
||||
|
||||
ABI2_FUNCTION_BEGIN __restore_r16_through_r17_and_deallocframe_before_tailcall
|
||||
{
|
||||
r17:16 = memd(fp+#-8)
|
||||
deallocframe
|
||||
jumpr lr
|
||||
}
|
||||
ABI2_FUNCTION_END __restore_r16_through_r17_and_deallocframe_before_tailcall
|
||||
|
||||
|
||||
ABI2_FUNCTION_BEGIN __restore_r16_through_r27_and_deallocframe
|
||||
r27:26 = memd(fp+#-48)
|
||||
{
|
||||
r25:24 = memd(fp+#-40)
|
||||
r23:22 = memd(fp+#-32)
|
||||
}
|
||||
{
|
||||
r21:20 = memd(fp+#-24)
|
||||
r19:18 = memd(fp+#-16)
|
||||
}
|
||||
{
|
||||
r17:16 = memd(fp+#-8)
|
||||
dealloc_return
|
||||
}
|
||||
ABI2_FUNCTION_END __restore_r16_through_r27_and_deallocframe
|
||||
|
||||
ABI2_FUNCTION_BEGIN __restore_r16_through_r25_and_deallocframe
|
||||
{
|
||||
r25:24 = memd(fp+#-40)
|
||||
r23:22 = memd(fp+#-32)
|
||||
}
|
||||
{
|
||||
r21:20 = memd(fp+#-24)
|
||||
r19:18 = memd(fp+#-16)
|
||||
}
|
||||
{
|
||||
r17:16 = memd(fp+#-8)
|
||||
dealloc_return
|
||||
}
|
||||
ABI2_FUNCTION_END __restore_r16_through_r25_and_deallocframe
|
||||
|
||||
ABI2_FUNCTION_BEGIN __restore_r16_through_r23_and_deallocframe
|
||||
{
|
||||
r23:22 = memd(fp+#-32)
|
||||
}
|
||||
{
|
||||
r21:20 = memd(fp+#-24)
|
||||
r19:18 = memd(fp+#-16)
|
||||
}
|
||||
{
|
||||
r17:16 = memd(fp+#-8)
|
||||
dealloc_return
|
||||
}
|
||||
ABI2_FUNCTION_END __restore_r16_through_r23_and_deallocframe
|
||||
|
||||
ABI2_FUNCTION_BEGIN __restore_r16_through_r21_and_deallocframe
|
||||
{
|
||||
r21:20 = memd(fp+#-24)
|
||||
r19:18 = memd(fp+#-16)
|
||||
}
|
||||
{
|
||||
r17:16 = memd(fp+#-8)
|
||||
dealloc_return
|
||||
}
|
||||
ABI2_FUNCTION_END __restore_r16_through_r21_and_deallocframe
|
||||
|
||||
ABI2_FUNCTION_BEGIN __restore_r16_through_r19_and_deallocframe
|
||||
{
|
||||
r19:18 = memd(fp+#-16)
|
||||
r17:16 = memd(fp+#-8)
|
||||
}
|
||||
{
|
||||
dealloc_return
|
||||
}
|
||||
ABI2_FUNCTION_END __restore_r16_through_r19_and_deallocframe
|
||||
|
||||
ABI2_FUNCTION_BEGIN __restore_r16_through_r17_and_deallocframe
|
||||
{
|
||||
r17:16 = memd(fp+#-8)
|
||||
dealloc_return
|
||||
}
|
||||
ABI2_FUNCTION_END __restore_r16_through_r17_and_deallocframe
|
||||
|
||||
ABI2_FUNCTION_BEGIN __deallocframe
|
||||
dealloc_return
|
||||
ABI2_FUNCTION_END __deallocframe
|
||||
@@ -0,0 +1,92 @@
|
||||
|
||||
FUNCTION_BEGIN __save_r27_through_r16
|
||||
memd(fp+#-48) = r17:16
|
||||
FALLTHROUGH_TAIL_CALL __save_r27_through_r16 __save_r27_through_r18
|
||||
memd(fp+#-40) = r19:18
|
||||
FALLTHROUGH_TAIL_CALL __save_r27_through_r18 __save_r27_through_r20
|
||||
memd(fp+#-32) = r21:20
|
||||
FALLTHROUGH_TAIL_CALL __save_r27_through_r20 __save_r27_through_r22
|
||||
memd(fp+#-24) = r23:22
|
||||
FALLTHROUGH_TAIL_CALL __save_r27_through_r22 __save_r27_through_r24
|
||||
memd(fp+#-16) = r25:24
|
||||
{
|
||||
memd(fp+#-8) = r27:26
|
||||
jumpr lr
|
||||
}
|
||||
FUNCTION_END __save_r27_through_r24
|
||||
|
||||
|
||||
FUNCTION_BEGIN __restore_r27_through_r20_and_deallocframe_before_sibcall
|
||||
{
|
||||
r21:20 = memd(fp+#-32)
|
||||
r23:22 = memd(fp+#-24)
|
||||
}
|
||||
FALLTHROUGH_TAIL_CALL __restore_r27_through_r20_and_deallocframe_before_sibcall __restore_r27_through_r24_and_deallocframe_before_sibcall
|
||||
{
|
||||
r25:24 = memd(fp+#-16)
|
||||
jump __restore_r27_through_r26_and_deallocframe_before_sibcall
|
||||
}
|
||||
FUNCTION_END __restore_r27_through_r24_and_deallocframe_before_sibcall
|
||||
|
||||
|
||||
FUNCTION_BEGIN __restore_r27_through_r16_and_deallocframe_before_sibcall
|
||||
r17:16 = memd(fp+#-48)
|
||||
FALLTHROUGH_TAIL_CALL __restore_r27_through_r16_and_deallocframe_before_sibcall __restore_r27_through_r18_and_deallocframe_before_sibcall
|
||||
{
|
||||
r19:18 = memd(fp+#-40)
|
||||
r21:20 = memd(fp+#-32)
|
||||
}
|
||||
FALLTHROUGH_TAIL_CALL __restore_r27_through_r18_and_deallocframe_before_sibcall __restore_r27_through_r22_and_deallocframe_before_sibcall
|
||||
{
|
||||
r23:22 = memd(fp+#-24)
|
||||
r25:24 = memd(fp+#-16)
|
||||
}
|
||||
FALLTHROUGH_TAIL_CALL __restore_r27_through_r22_and_deallocframe_before_sibcall __restore_r27_through_r26_and_deallocframe_before_sibcall
|
||||
{
|
||||
r27:26 = memd(fp+#-8)
|
||||
deallocframe
|
||||
jumpr lr
|
||||
}
|
||||
FUNCTION_END __restore_r27_through_r26_and_deallocframe_before_sibcall
|
||||
|
||||
|
||||
FUNCTION_BEGIN __restore_r27_through_r16_and_deallocframe
|
||||
{
|
||||
r17:16 = memd(fp+#-48)
|
||||
r19:18 = memd(fp+#-40)
|
||||
}
|
||||
FALLTHROUGH_TAIL_CALL __restore_r27_through_r16_and_deallocframe __restore_r27_through_r20_and_deallocframe
|
||||
{
|
||||
r21:20 = memd(fp+#-32)
|
||||
r23:22 = memd(fp+#-24)
|
||||
}
|
||||
FALLTHROUGH_TAIL_CALL __restore_r27_through_r20_and_deallocframe __restore_r27_through_r24_and_deallocframe
|
||||
{
|
||||
lr = memw(fp+#4)
|
||||
r25:24 = memd(fp+#-16)
|
||||
}
|
||||
{
|
||||
r27:26 = memd(fp+#-8)
|
||||
deallocframe
|
||||
jumpr lr
|
||||
}
|
||||
FUNCTION_END __restore_r27_through_r24_and_deallocframe
|
||||
|
||||
|
||||
FUNCTION_BEGIN __restore_r27_through_r18_and_deallocframe
|
||||
{
|
||||
r19:18 = memd(fp+#-40)
|
||||
r21:20 = memd(fp+#-32)
|
||||
}
|
||||
FALLTHROUGH_TAIL_CALL __restore_r27_through_r18_and_deallocframe __restore_r27_through_r22_and_deallocframe
|
||||
{
|
||||
r23:22 = memd(fp+#-24)
|
||||
r25:24 = memd(fp+#-16)
|
||||
}
|
||||
FALLTHROUGH_TAIL_CALL __restore_r27_through_r22_and_deallocframe __restore_r27_through_r26_and_deallocframe
|
||||
{
|
||||
r27:26 = memd(fp+#-8)
|
||||
deallocframe
|
||||
}
|
||||
jumpr lr
|
||||
FUNCTION_END __restore_r27_through_r26_and_deallocframe
|
||||
@@ -10,3 +10,11 @@
|
||||
.size \name, . - \name
|
||||
.endm
|
||||
|
||||
.macro FALLTHROUGH_TAIL_CALL name0 name1
|
||||
.size \name0, . - \name0
|
||||
.globl \name1
|
||||
.type \name1, @function
|
||||
.falign
|
||||
\name1:
|
||||
.endm
|
||||
|
||||
|
||||
@@ -31,6 +31,35 @@ FUNCTION_BEGIN __hexagon_memcpy_likely_aligned_min32bytes_mult8bytes
|
||||
}
|
||||
FUNCTION_END __hexagon_memcpy_likely_aligned_min32bytes_mult8bytes
|
||||
|
||||
FUNCTION_BEGIN __hexagon_memcpy_dwloop
|
||||
{
|
||||
r5:4 = memd(r1)
|
||||
r3 = #-3
|
||||
}
|
||||
{
|
||||
memd(r0++#8) = r5:4
|
||||
r5:4 = memd(r1+#8)
|
||||
r3 += lsr(r2,#3)
|
||||
}
|
||||
{
|
||||
memd(r0++#8) = r5:4
|
||||
r5:4 = memd(r1+#16)
|
||||
r1 = add(r1,#24)
|
||||
loop0(1f,r3)
|
||||
}
|
||||
.falign
|
||||
1:
|
||||
{
|
||||
memd(r0++#8) = r5:4
|
||||
r5:4 = memd(r1++#8)
|
||||
}:endloop0
|
||||
{
|
||||
memd(r0) = r5:4
|
||||
r0 -= add(r2,#-8)
|
||||
jumpr r31
|
||||
}
|
||||
FUNCTION_END __hexagon_memcpy_dwloop
|
||||
|
||||
.Lmemcpy_call:
|
||||
|
||||
jump memcpy@PLT
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::int::{DInt, Int, MinInt};
|
||||
use crate::support::{DInt, Int, MinInt};
|
||||
|
||||
trait UAddSub: DInt + Int {
|
||||
fn uadd(self, other: Self) -> Self {
|
||||
|
||||
@@ -1,295 +0,0 @@
|
||||
//! Integers used for wide operations, larger than `u128`.
|
||||
|
||||
#![allow(unused)]
|
||||
|
||||
use core::{fmt, ops};
|
||||
|
||||
use crate::int::{DInt, HInt, Int, MinInt};
|
||||
|
||||
const WORD_LO_MASK: u64 = 0x00000000ffffffff;
|
||||
const WORD_HI_MASK: u64 = 0xffffffff00000000;
|
||||
const WORD_FULL_MASK: u64 = 0xffffffffffffffff;
|
||||
const U128_LO_MASK: u128 = u64::MAX as u128;
|
||||
const U128_HI_MASK: u128 = (u64::MAX as u128) << 64;
|
||||
|
||||
/// A 256-bit unsigned integer represented as 4 64-bit limbs.
|
||||
///
|
||||
/// Each limb is a native-endian number, but the array is little-limb-endian.
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
|
||||
pub struct u256(pub [u64; 4]);
|
||||
|
||||
impl u256 {
|
||||
pub const MAX: Self = Self([u64::MAX, u64::MAX, u64::MAX, u64::MAX]);
|
||||
|
||||
/// Reinterpret as a signed integer
|
||||
pub fn signed(self) -> i256 {
|
||||
i256(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/// A 256-bit signed integer represented as 4 64-bit limbs.
|
||||
///
|
||||
/// Each limb is a native-endian number, but the array is little-limb-endian.
|
||||
#[allow(non_camel_case_types)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
|
||||
pub struct i256(pub [u64; 4]);
|
||||
|
||||
impl i256 {
|
||||
/// Reinterpret as an unsigned integer
|
||||
pub fn unsigned(self) -> u256 {
|
||||
u256(self.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl MinInt for u256 {
|
||||
type OtherSign = i256;
|
||||
|
||||
type Unsigned = u256;
|
||||
|
||||
const SIGNED: bool = false;
|
||||
const BITS: u32 = 256;
|
||||
const ZERO: Self = Self([0u64; 4]);
|
||||
const ONE: Self = Self([1, 0, 0, 0]);
|
||||
const MIN: Self = Self([0u64; 4]);
|
||||
const MAX: Self = Self([u64::MAX; 4]);
|
||||
}
|
||||
|
||||
impl MinInt for i256 {
|
||||
type OtherSign = u256;
|
||||
|
||||
type Unsigned = u256;
|
||||
|
||||
const SIGNED: bool = false;
|
||||
const BITS: u32 = 256;
|
||||
const ZERO: Self = Self([0u64; 4]);
|
||||
const ONE: Self = Self([1, 0, 0, 0]);
|
||||
const MIN: Self = Self([0, 0, 0, 1 << 63]);
|
||||
const MAX: Self = Self([u64::MAX, u64::MAX, u64::MAX, u64::MAX >> 1]);
|
||||
}
|
||||
|
||||
macro_rules! impl_common {
|
||||
($ty:ty) => {
|
||||
impl ops::BitOr for $ty {
|
||||
type Output = Self;
|
||||
|
||||
fn bitor(mut self, rhs: Self) -> Self::Output {
|
||||
self.0[0] |= rhs.0[0];
|
||||
self.0[1] |= rhs.0[1];
|
||||
self.0[2] |= rhs.0[2];
|
||||
self.0[3] |= rhs.0[3];
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Not for $ty {
|
||||
type Output = Self;
|
||||
|
||||
fn not(self) -> Self::Output {
|
||||
Self([!self.0[0], !self.0[1], !self.0[2], !self.0[3]])
|
||||
}
|
||||
}
|
||||
|
||||
impl ops::Shl<u32> for $ty {
|
||||
type Output = Self;
|
||||
|
||||
fn shl(self, rhs: u32) -> Self::Output {
|
||||
unimplemented!("only used to meet trait bounds")
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
impl_common!(i256);
|
||||
impl_common!(u256);
|
||||
|
||||
impl ops::Shr<u32> for u256 {
|
||||
type Output = Self;
|
||||
|
||||
fn shr(self, rhs: u32) -> Self::Output {
|
||||
assert!(rhs < Self::BITS, "attempted to shift right with overflow");
|
||||
|
||||
if rhs == 0 {
|
||||
return self;
|
||||
}
|
||||
|
||||
let mut ret = self;
|
||||
let byte_shift = rhs / 64;
|
||||
let bit_shift = rhs % 64;
|
||||
|
||||
for idx in 0..4 {
|
||||
let base_idx = idx + byte_shift as usize;
|
||||
|
||||
let Some(base) = ret.0.get(base_idx) else {
|
||||
ret.0[idx] = 0;
|
||||
continue;
|
||||
};
|
||||
|
||||
let mut new_val = base >> bit_shift;
|
||||
|
||||
if let Some(new) = ret.0.get(base_idx + 1) {
|
||||
new_val |= new.overflowing_shl(64 - bit_shift).0;
|
||||
}
|
||||
|
||||
ret.0[idx] = new_val;
|
||||
}
|
||||
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! word {
|
||||
(1, $val:expr) => {
|
||||
(($val >> (32 * 3)) & Self::from(WORD_LO_MASK)) as u64
|
||||
};
|
||||
(2, $val:expr) => {
|
||||
(($val >> (32 * 2)) & Self::from(WORD_LO_MASK)) as u64
|
||||
};
|
||||
(3, $val:expr) => {
|
||||
(($val >> (32 * 1)) & Self::from(WORD_LO_MASK)) as u64
|
||||
};
|
||||
(4, $val:expr) => {
|
||||
(($val >> (32 * 0)) & Self::from(WORD_LO_MASK)) as u64
|
||||
};
|
||||
}
|
||||
|
||||
impl HInt for u128 {
|
||||
type D = u256;
|
||||
|
||||
fn widen(self) -> Self::D {
|
||||
let w0 = self & u128::from(u64::MAX);
|
||||
let w1 = (self >> u64::BITS) & u128::from(u64::MAX);
|
||||
u256([w0 as u64, w1 as u64, 0, 0])
|
||||
}
|
||||
|
||||
fn zero_widen(self) -> Self::D {
|
||||
self.widen()
|
||||
}
|
||||
|
||||
fn zero_widen_mul(self, rhs: Self) -> Self::D {
|
||||
let product11: u64 = word!(1, self) * word!(1, rhs);
|
||||
let product12: u64 = word!(1, self) * word!(2, rhs);
|
||||
let product13: u64 = word!(1, self) * word!(3, rhs);
|
||||
let product14: u64 = word!(1, self) * word!(4, rhs);
|
||||
let product21: u64 = word!(2, self) * word!(1, rhs);
|
||||
let product22: u64 = word!(2, self) * word!(2, rhs);
|
||||
let product23: u64 = word!(2, self) * word!(3, rhs);
|
||||
let product24: u64 = word!(2, self) * word!(4, rhs);
|
||||
let product31: u64 = word!(3, self) * word!(1, rhs);
|
||||
let product32: u64 = word!(3, self) * word!(2, rhs);
|
||||
let product33: u64 = word!(3, self) * word!(3, rhs);
|
||||
let product34: u64 = word!(3, self) * word!(4, rhs);
|
||||
let product41: u64 = word!(4, self) * word!(1, rhs);
|
||||
let product42: u64 = word!(4, self) * word!(2, rhs);
|
||||
let product43: u64 = word!(4, self) * word!(3, rhs);
|
||||
let product44: u64 = word!(4, self) * word!(4, rhs);
|
||||
|
||||
let sum0: u128 = u128::from(product44);
|
||||
let sum1: u128 = u128::from(product34) + u128::from(product43);
|
||||
let sum2: u128 = u128::from(product24) + u128::from(product33) + u128::from(product42);
|
||||
let sum3: u128 = u128::from(product14)
|
||||
+ u128::from(product23)
|
||||
+ u128::from(product32)
|
||||
+ u128::from(product41);
|
||||
let sum4: u128 = u128::from(product13) + u128::from(product22) + u128::from(product31);
|
||||
let sum5: u128 = u128::from(product12) + u128::from(product21);
|
||||
let sum6: u128 = u128::from(product11);
|
||||
|
||||
let r0: u128 =
|
||||
(sum0 & u128::from(WORD_FULL_MASK)) + ((sum1 & u128::from(WORD_LO_MASK)) << 32);
|
||||
let r1: u128 = (sum0 >> 64)
|
||||
+ ((sum1 >> 32) & u128::from(WORD_FULL_MASK))
|
||||
+ (sum2 & u128::from(WORD_FULL_MASK))
|
||||
+ ((sum3 << 32) & u128::from(WORD_HI_MASK));
|
||||
|
||||
let (lo, carry) = r0.overflowing_add(r1 << 64);
|
||||
let hi = (r1 >> 64)
|
||||
+ (sum1 >> 96)
|
||||
+ (sum2 >> 64)
|
||||
+ (sum3 >> 32)
|
||||
+ sum4
|
||||
+ (sum5 << 32)
|
||||
+ (sum6 << 64)
|
||||
+ u128::from(carry);
|
||||
|
||||
u256([
|
||||
(lo & U128_LO_MASK) as u64,
|
||||
((lo >> 64) & U128_LO_MASK) as u64,
|
||||
(hi & U128_LO_MASK) as u64,
|
||||
((hi >> 64) & U128_LO_MASK) as u64,
|
||||
])
|
||||
}
|
||||
|
||||
fn widen_mul(self, rhs: Self) -> Self::D {
|
||||
self.zero_widen_mul(rhs)
|
||||
}
|
||||
|
||||
fn widen_hi(self) -> Self::D {
|
||||
self.widen() << <Self as MinInt>::BITS
|
||||
}
|
||||
}
|
||||
|
||||
impl HInt for i128 {
|
||||
type D = i256;
|
||||
|
||||
fn widen(self) -> Self::D {
|
||||
let mut ret = self.unsigned().zero_widen().signed();
|
||||
if self.is_negative() {
|
||||
ret.0[2] = u64::MAX;
|
||||
ret.0[3] = u64::MAX;
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn zero_widen(self) -> Self::D {
|
||||
self.unsigned().zero_widen().signed()
|
||||
}
|
||||
|
||||
fn zero_widen_mul(self, rhs: Self) -> Self::D {
|
||||
self.unsigned().zero_widen_mul(rhs.unsigned()).signed()
|
||||
}
|
||||
|
||||
fn widen_mul(self, rhs: Self) -> Self::D {
|
||||
unimplemented!("signed i128 widening multiply is not used")
|
||||
}
|
||||
|
||||
fn widen_hi(self) -> Self::D {
|
||||
self.widen() << <Self as MinInt>::BITS
|
||||
}
|
||||
}
|
||||
|
||||
impl DInt for u256 {
|
||||
type H = u128;
|
||||
|
||||
fn lo(self) -> Self::H {
|
||||
let mut tmp = [0u8; 16];
|
||||
tmp[..8].copy_from_slice(&self.0[0].to_le_bytes());
|
||||
tmp[8..].copy_from_slice(&self.0[1].to_le_bytes());
|
||||
u128::from_le_bytes(tmp)
|
||||
}
|
||||
|
||||
fn hi(self) -> Self::H {
|
||||
let mut tmp = [0u8; 16];
|
||||
tmp[..8].copy_from_slice(&self.0[2].to_le_bytes());
|
||||
tmp[8..].copy_from_slice(&self.0[3].to_le_bytes());
|
||||
u128::from_le_bytes(tmp)
|
||||
}
|
||||
}
|
||||
|
||||
impl DInt for i256 {
|
||||
type H = i128;
|
||||
|
||||
fn lo(self) -> Self::H {
|
||||
let mut tmp = [0u8; 16];
|
||||
tmp[..8].copy_from_slice(&self.0[0].to_le_bytes());
|
||||
tmp[8..].copy_from_slice(&self.0[1].to_le_bytes());
|
||||
i128::from_le_bytes(tmp)
|
||||
}
|
||||
|
||||
fn hi(self) -> Self::H {
|
||||
let mut tmp = [0u8; 16];
|
||||
tmp[..8].copy_from_slice(&self.0[2].to_le_bytes());
|
||||
tmp[8..].copy_from_slice(&self.0[3].to_le_bytes());
|
||||
i128::from_le_bytes(tmp)
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
pub(crate) use implementation::{leading_zeros_default, leading_zeros_riscv};
|
||||
|
||||
mod implementation {
|
||||
use crate::int::{CastFrom, Int};
|
||||
use crate::support::{CastFrom, Int};
|
||||
|
||||
/// Returns the number of leading binary zeros in `x`.
|
||||
#[allow(dead_code)]
|
||||
|
||||
@@ -1,18 +1,10 @@
|
||||
mod specialized_div_rem;
|
||||
|
||||
pub mod addsub;
|
||||
mod big;
|
||||
pub mod bswap;
|
||||
pub mod leading_zeros;
|
||||
pub mod mul;
|
||||
pub mod sdiv;
|
||||
pub mod shift;
|
||||
pub mod trailing_zeros;
|
||||
mod traits;
|
||||
pub mod udiv;
|
||||
|
||||
pub use big::{i256, u256};
|
||||
#[cfg(not(feature = "unstable-public-internals"))]
|
||||
pub(crate) use traits::{CastFrom, CastInto, DInt, HInt, Int, MinInt};
|
||||
#[cfg(feature = "unstable-public-internals")]
|
||||
pub use traits::{CastFrom, CastInto, DInt, HInt, Int, MinInt};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::int::{DInt, HInt, Int};
|
||||
use crate::support::{DInt, HInt, Int};
|
||||
|
||||
trait Mul: DInt + Int
|
||||
where
|
||||
@@ -98,11 +98,63 @@ fn $fn(lhs: $iD, rhs: $iD) -> ($iD, bool) {
|
||||
impl_signed_mulo!(i128_overflowing_mul, i128, u128);
|
||||
|
||||
intrinsics! {
|
||||
// Ancient Egyptian/Ethiopian/Russian multiplication method
|
||||
// see https://en.wikipedia.org/wiki/Ancient_Egyptian_multiplication
|
||||
//
|
||||
// This is a long-available stock algorithm; e.g. it is documented in
|
||||
// Knuth's "The Art of Computer Programming" volume 2 (under the section
|
||||
// "Evaluation of Powers") since at least the 2nd edition (1981).
|
||||
//
|
||||
// The main attraction of this method is that it implements (software)
|
||||
// multiplication atop four simple operations: doubling, halving, checking
|
||||
// if a value is even/odd, and addition. This is *not* considered to be the
|
||||
// fastest multiplication method, but it may be amongst the simplest (and
|
||||
// smallest with respect to code size).
|
||||
//
|
||||
// for reference, see also implementation from gcc
|
||||
// https://raw.githubusercontent.com/gcc-mirror/gcc/master/libgcc/config/epiphany/mulsi3.c
|
||||
//
|
||||
// and from LLVM (in relatively readable RISC-V assembly):
|
||||
// https://github.com/llvm/llvm-project/blob/main/compiler-rt/lib/builtins/riscv/int_mul_impl.inc
|
||||
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64", target_arch = "m68k"))]
|
||||
pub extern "C" fn __mulsi3(a: u32, b: u32) -> u32 {
|
||||
let (mut a, mut b) = (a, b);
|
||||
let mut r: u32 = 0;
|
||||
|
||||
while a > 0 {
|
||||
if a & 1 > 0 {
|
||||
r = r.wrapping_add(b);
|
||||
}
|
||||
a >>= 1;
|
||||
b <<= 1;
|
||||
}
|
||||
|
||||
r
|
||||
}
|
||||
|
||||
#[maybe_use_optimized_c_shim]
|
||||
#[arm_aeabi_alias = __aeabi_lmul]
|
||||
#[cfg(any(not(any(target_arch = "riscv32", target_arch = "riscv64")), target_feature = "m"))]
|
||||
pub extern "C" fn __muldi3(a: u64, b: u64) -> u64 {
|
||||
a.mul(b)
|
||||
#[cfg(all(any(target_arch = "riscv32", target_arch = "riscv64"), not(target_feature = "m")))]
|
||||
{
|
||||
let (mut a, mut b) = (a, b);
|
||||
let mut r: u64 = 0;
|
||||
|
||||
while a > 0 {
|
||||
if a & 1 > 0 {
|
||||
r = r.wrapping_add(b);
|
||||
}
|
||||
a >>= 1;
|
||||
b <<= 1;
|
||||
}
|
||||
|
||||
r
|
||||
}
|
||||
|
||||
#[cfg(not(all(any(target_arch = "riscv32", target_arch = "riscv64"), not(target_feature = "m"))))]
|
||||
{
|
||||
a.mul(b)
|
||||
}
|
||||
}
|
||||
|
||||
pub extern "C" fn __multi3(a: i128, b: i128) -> i128 {
|
||||
@@ -139,4 +191,5 @@ pub extern "C" fn __rust_u128_mulo(a: u128, b: u128, oflow: &mut i32) -> u128 {
|
||||
*oflow = o.into();
|
||||
mul
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::int::{DInt, HInt, Int, MinInt};
|
||||
use crate::support::{DInt, HInt, Int, MinInt};
|
||||
|
||||
trait Ashl: DInt {
|
||||
/// Returns `a << b`, requires `b < Self::BITS`
|
||||
|
||||
@@ -144,7 +144,7 @@ fn u64_by_u64_div_rem(duo: u64, div: u64) -> (u64, u64) {
|
||||
target_family = "wasm",
|
||||
not(any(target_pointer_width = "16", target_pointer_width = "32")),
|
||||
),
|
||||
not(all(not(feature = "no-asm"), target_arch = "x86_64")),
|
||||
not(all(feature = "arch", target_arch = "x86_64")),
|
||||
not(any(target_arch = "sparc", target_arch = "sparc64"))
|
||||
))]
|
||||
impl_trifecta!(
|
||||
@@ -165,7 +165,7 @@ fn u64_by_u64_div_rem(duo: u64, div: u64) -> (u64, u64) {
|
||||
target_family = "wasm",
|
||||
not(any(target_pointer_width = "16", target_pointer_width = "32")),
|
||||
)),
|
||||
not(all(not(feature = "no-asm"), target_arch = "x86_64")),
|
||||
not(all(feature = "arch", target_arch = "x86_64")),
|
||||
not(any(target_arch = "sparc", target_arch = "sparc64"))
|
||||
))]
|
||||
impl_delegate!(
|
||||
@@ -186,7 +186,7 @@ fn u64_by_u64_div_rem(duo: u64, div: u64) -> (u64, u64) {
|
||||
///
|
||||
/// If the quotient does not fit in a `u64`, a floating point exception occurs.
|
||||
/// If `div == 0`, then a division by zero exception occurs.
|
||||
#[cfg(all(not(feature = "no-asm"), target_arch = "x86_64"))]
|
||||
#[cfg(all(feature = "arch", target_arch = "x86_64"))]
|
||||
#[inline]
|
||||
unsafe fn u128_by_u64_div_rem(duo: u128, div: u64) -> (u64, u64) {
|
||||
let duo_lo = duo as u64;
|
||||
@@ -208,7 +208,7 @@ unsafe fn u128_by_u64_div_rem(duo: u128, div: u64) -> (u64, u64) {
|
||||
}
|
||||
|
||||
// use `asymmetric` instead of `trifecta` on x86_64
|
||||
#[cfg(all(not(feature = "no-asm"), target_arch = "x86_64"))]
|
||||
#[cfg(all(feature = "arch", target_arch = "x86_64"))]
|
||||
impl_asymmetric!(
|
||||
u128_div_rem,
|
||||
zero_div_fn,
|
||||
@@ -237,7 +237,7 @@ fn u32_by_u32_div_rem(duo: u32, div: u32) -> (u32, u32) {
|
||||
// When not on x86 and the pointer width is not 64, use `delegate` since the division size is larger
|
||||
// than register size.
|
||||
#[cfg(all(
|
||||
not(all(not(feature = "no-asm"), target_arch = "x86")),
|
||||
not(all(feature = "arch", target_arch = "x86")),
|
||||
not(target_pointer_width = "64")
|
||||
))]
|
||||
impl_delegate!(
|
||||
@@ -254,7 +254,7 @@ fn u32_by_u32_div_rem(duo: u32, div: u32) -> (u32, u32) {
|
||||
|
||||
// When not on x86 and the pointer width is 64, use `binary_long`.
|
||||
#[cfg(all(
|
||||
not(all(not(feature = "no-asm"), target_arch = "x86")),
|
||||
not(all(feature = "arch", target_arch = "x86")),
|
||||
target_pointer_width = "64"
|
||||
))]
|
||||
impl_binary_long!(
|
||||
@@ -272,7 +272,7 @@ fn u32_by_u32_div_rem(duo: u32, div: u32) -> (u32, u32) {
|
||||
///
|
||||
/// If the quotient does not fit in a `u32`, a floating point exception occurs.
|
||||
/// If `div == 0`, then a division by zero exception occurs.
|
||||
#[cfg(all(not(feature = "no-asm"), target_arch = "x86"))]
|
||||
#[cfg(all(feature = "arch", target_arch = "x86"))]
|
||||
#[inline]
|
||||
unsafe fn u64_by_u32_div_rem(duo: u64, div: u32) -> (u32, u32) {
|
||||
let duo_lo = duo as u32;
|
||||
@@ -294,7 +294,7 @@ unsafe fn u64_by_u32_div_rem(duo: u64, div: u32) -> (u32, u32) {
|
||||
}
|
||||
|
||||
// use `asymmetric` instead of `delegate` on x86
|
||||
#[cfg(all(not(feature = "no-asm"), target_arch = "x86"))]
|
||||
#[cfg(all(feature = "arch", target_arch = "x86"))]
|
||||
impl_asymmetric!(
|
||||
u64_div_rem,
|
||||
zero_div_fn,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
pub(crate) use implementation::trailing_zeros;
|
||||
|
||||
mod implementation {
|
||||
use crate::int::{CastFrom, Int};
|
||||
use crate::support::{CastFrom, Int};
|
||||
|
||||
/// Returns number of trailing binary zeros in `x`.
|
||||
#[allow(dead_code)]
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
pub use crate::support::{CastFrom, CastInto, Int, MinInt};
|
||||
|
||||
/// Trait for integers twice the bit width of another integer. This is implemented for all
|
||||
/// primitives except for `u8`, because there is not a smaller primitive.
|
||||
pub trait DInt: MinInt {
|
||||
/// Integer that is half the bit width of the integer this trait is implemented for
|
||||
type H: HInt<D = Self>;
|
||||
|
||||
/// Returns the low half of `self`
|
||||
fn lo(self) -> Self::H;
|
||||
/// Returns the high half of `self`
|
||||
fn hi(self) -> Self::H;
|
||||
/// Returns the low and high halves of `self` as a tuple
|
||||
fn lo_hi(self) -> (Self::H, Self::H) {
|
||||
(self.lo(), self.hi())
|
||||
}
|
||||
/// Constructs an integer using lower and higher half parts
|
||||
fn from_lo_hi(lo: Self::H, hi: Self::H) -> Self {
|
||||
lo.zero_widen() | hi.widen_hi()
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for integers half the bit width of another integer. This is implemented for all
|
||||
/// primitives except for `u128`, because it there is not a larger primitive.
|
||||
pub trait HInt: Int {
|
||||
/// Integer that is double the bit width of the integer this trait is implemented for
|
||||
type D: DInt<H = Self> + MinInt;
|
||||
|
||||
// NB: some of the below methods could have default implementations (e.g. `widen_hi`), but for
|
||||
// unknown reasons this can cause infinite recursion when optimizations are disabled. See
|
||||
// <https://github.com/rust-lang/compiler-builtins/pull/707> for context.
|
||||
|
||||
/// Widens (using default extension) the integer to have double bit width
|
||||
fn widen(self) -> Self::D;
|
||||
/// Widens (zero extension only) the integer to have double bit width. This is needed to get
|
||||
/// around problems with associated type bounds (such as `Int<Othersign: DInt>`) being unstable
|
||||
fn zero_widen(self) -> Self::D;
|
||||
/// Widens the integer to have double bit width and shifts the integer into the higher bits
|
||||
fn widen_hi(self) -> Self::D;
|
||||
/// Widening multiplication with zero widening. This cannot overflow.
|
||||
fn zero_widen_mul(self, rhs: Self) -> Self::D;
|
||||
/// Widening multiplication. This cannot overflow.
|
||||
fn widen_mul(self, rhs: Self) -> Self::D;
|
||||
}
|
||||
|
||||
macro_rules! impl_d_int {
|
||||
($($X:ident $D:ident),*) => {
|
||||
$(
|
||||
impl DInt for $D {
|
||||
type H = $X;
|
||||
|
||||
fn lo(self) -> Self::H {
|
||||
self as $X
|
||||
}
|
||||
fn hi(self) -> Self::H {
|
||||
(self >> <$X as MinInt>::BITS) as $X
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_h_int {
|
||||
($($H:ident $uH:ident $X:ident),*) => {
|
||||
$(
|
||||
impl HInt for $H {
|
||||
type D = $X;
|
||||
|
||||
fn widen(self) -> Self::D {
|
||||
self as $X
|
||||
}
|
||||
fn zero_widen(self) -> Self::D {
|
||||
(self as $uH) as $X
|
||||
}
|
||||
fn zero_widen_mul(self, rhs: Self) -> Self::D {
|
||||
self.zero_widen().wrapping_mul(rhs.zero_widen())
|
||||
}
|
||||
fn widen_mul(self, rhs: Self) -> Self::D {
|
||||
self.widen().wrapping_mul(rhs.widen())
|
||||
}
|
||||
fn widen_hi(self) -> Self::D {
|
||||
(self as $X) << <Self as MinInt>::BITS
|
||||
}
|
||||
}
|
||||
)*
|
||||
};
|
||||
}
|
||||
|
||||
impl_d_int!(u8 u16, u16 u32, u32 u64, u64 u128, i8 i16, i16 i32, i32 i64, i64 i128);
|
||||
impl_h_int!(
|
||||
u8 u8 u16,
|
||||
u16 u16 u32,
|
||||
u32 u32 u64,
|
||||
u64 u64 u128,
|
||||
i8 u8 i16,
|
||||
i16 u16 i32,
|
||||
i32 u32 i64,
|
||||
i64 u64 i128
|
||||
);
|
||||
@@ -48,6 +48,9 @@
|
||||
pub mod sync;
|
||||
|
||||
// `libm` expects its `support` module to be available in the crate root.
|
||||
#[cfg(feature = "unstable-public-internals")]
|
||||
pub use math::libm_math::support;
|
||||
#[cfg(not(feature = "unstable-public-internals"))]
|
||||
use math::libm_math::support;
|
||||
|
||||
#[cfg(target_arch = "arm")]
|
||||
@@ -60,7 +63,10 @@
|
||||
// in the builtins-test tests. So this is a way of enabling the module during testing.
|
||||
#[cfg(all(
|
||||
target_arch = "aarch64",
|
||||
any(target_feature = "outline-atomics", feature = "mangled-names")
|
||||
any(
|
||||
target_feature = "outline-atomics",
|
||||
feature = "unstable-public-internals"
|
||||
)
|
||||
))]
|
||||
pub mod aarch64_outline_atomics;
|
||||
|
||||
@@ -70,9 +76,6 @@
|
||||
#[cfg(target_arch = "hexagon")]
|
||||
pub mod hexagon;
|
||||
|
||||
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
|
||||
pub mod riscv;
|
||||
|
||||
#[cfg(target_arch = "x86")]
|
||||
pub mod x86;
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ pub extern "unadjusted" fn $name( $($argname: $ty),* ) $(-> $ret)? {
|
||||
$($body)*
|
||||
}
|
||||
|
||||
#[cfg(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64"), not(feature = "mangled-names")))]
|
||||
#[cfg(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64"), feature = "unmangled-names"))]
|
||||
mod $name {
|
||||
#[unsafe(no_mangle)]
|
||||
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
|
||||
@@ -290,7 +290,7 @@ mod $name {
|
||||
$($body)*
|
||||
}
|
||||
|
||||
#[cfg(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64"), not(feature = "mangled-names")))]
|
||||
#[cfg(all(target_vendor = "apple", any(target_arch = "x86", target_arch = "x86_64"), feature = "unmangled-names"))]
|
||||
mod $name {
|
||||
#[unsafe(no_mangle)]
|
||||
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
|
||||
@@ -331,7 +331,7 @@ mod $name {
|
||||
$($body)*
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "arm", not(feature = "mangled-names")))]
|
||||
#[cfg(all(target_arch = "arm", feature = "unmangled-names"))]
|
||||
mod $name {
|
||||
#[unsafe(no_mangle)]
|
||||
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
|
||||
@@ -341,7 +341,7 @@ mod $name {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(target_arch = "arm", not(feature = "mangled-names")))]
|
||||
#[cfg(all(target_arch = "arm", feature = "unmangled-names"))]
|
||||
mod $alias {
|
||||
#[unsafe(no_mangle)]
|
||||
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
|
||||
@@ -392,7 +392,7 @@ extern "aapcs" fn $alias( $($argname: $ty),* ) $(-> $ret)? {
|
||||
intrinsics!($($rest)*);
|
||||
);
|
||||
|
||||
// C mem* functions are only generated when the "mem" feature is enabled.
|
||||
// C mem* functions are only exposed via `no_mangle` when the "mem" feature is enabled.
|
||||
(
|
||||
#[mem_builtin]
|
||||
$(#[$($attr:tt)*])*
|
||||
@@ -407,7 +407,7 @@ extern "aapcs" fn $alias( $($argname: $ty),* ) $(-> $ret)? {
|
||||
$($body)*
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "mem", not(feature = "mangled-names")))]
|
||||
#[cfg(all(feature = "mem", feature = "unmangled-names"))]
|
||||
mod $name {
|
||||
$(#[$($attr)*])*
|
||||
#[unsafe(no_mangle)]
|
||||
@@ -435,7 +435,7 @@ mod $name {
|
||||
pub mod $name {
|
||||
#[unsafe(naked)]
|
||||
$(#[$($attr)*])*
|
||||
#[cfg_attr(not(feature = "mangled-names"), unsafe(no_mangle))]
|
||||
#[cfg_attr(feature = "unmangled-names", unsafe(no_mangle))]
|
||||
#[cfg_attr(not(any(all(windows, target_env = "gnu"), target_os = "cygwin")), linkage = "weak")]
|
||||
pub unsafe extern $abi fn $name( $($argname: $ty),* ) $(-> $ret)? {
|
||||
$($body)*
|
||||
@@ -470,7 +470,7 @@ pub mod $name {
|
||||
$($body)*
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "mangled-names"))]
|
||||
#[cfg(feature = "unmangled-names")]
|
||||
mod $name {
|
||||
$(#[$($attr)*])*
|
||||
#[unsafe(no_mangle)]
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
// ptr::add in these loops will wrap. And if compiler-builtins is compiled with cfg(ub_checks),
|
||||
// this will fail a UB check at runtime.
|
||||
//
|
||||
// Since this scenario is UB, we are within our rights hit this check and halt execution...
|
||||
// Since this scenario is UB, we are within our rights to hit this check and halt execution...
|
||||
// But we are also within our rights to try to make it work.
|
||||
// We use wrapping_add/wrapping_sub for pointer arithmetic in this module in an attempt to support
|
||||
// this use. Of course this is not a guarantee that such use will work, it just means that this
|
||||
@@ -35,7 +35,7 @@
|
||||
16
|
||||
};
|
||||
|
||||
#[cfg(feature = "mem-unaligned")]
|
||||
#[cfg(mem_unaligned)]
|
||||
unsafe fn read_usize_unaligned(x: *const usize) -> usize {
|
||||
// Do not use `core::ptr::read_unaligned` here, since it calls `copy_nonoverlapping` which
|
||||
// is translated to memcpy in LLVM.
|
||||
@@ -46,7 +46,7 @@ unsafe fn read_usize_unaligned(x: *const usize) -> usize {
|
||||
/// Loads a `T`-sized chunk from `src` into `dst` at offset `offset`, if that does not exceed
|
||||
/// `load_sz`. The offset pointers must both be `T`-aligned. Returns the new offset, advanced by the
|
||||
/// chunk size if a load happened.
|
||||
#[cfg(not(feature = "mem-unaligned"))]
|
||||
#[cfg(not(mem_unaligned))]
|
||||
#[inline(always)]
|
||||
unsafe fn load_chunk_aligned<T: Copy>(
|
||||
src: *const usize,
|
||||
@@ -66,7 +66,7 @@ unsafe fn load_chunk_aligned<T: Copy>(
|
||||
/// Load `load_sz` many bytes from `src`, which must be usize-aligned. Acts as if we did a `usize`
|
||||
/// read with the out-of-bounds part filled with 0s.
|
||||
/// `load_sz` be strictly less than `WORD_SIZE`.
|
||||
#[cfg(not(feature = "mem-unaligned"))]
|
||||
#[cfg(not(mem_unaligned))]
|
||||
#[inline(always)]
|
||||
unsafe fn load_aligned_partial(src: *const usize, load_sz: usize) -> usize {
|
||||
debug_assert!(load_sz < WORD_SIZE);
|
||||
@@ -88,7 +88,7 @@ unsafe fn load_aligned_partial(src: *const usize, load_sz: usize) -> usize {
|
||||
/// `usize`-aligned. The bytes are returned as the *last* bytes of the return value, i.e., this acts
|
||||
/// as if we had done a `usize` read from `src`, with the out-of-bounds part filled with 0s.
|
||||
/// `load_sz` be strictly less than `WORD_SIZE`.
|
||||
#[cfg(not(feature = "mem-unaligned"))]
|
||||
#[cfg(not(mem_unaligned))]
|
||||
#[inline(always)]
|
||||
unsafe fn load_aligned_end_partial(src: *const usize, load_sz: usize) -> usize {
|
||||
debug_assert!(load_sz < WORD_SIZE);
|
||||
@@ -136,7 +136,7 @@ unsafe fn copy_forward_aligned_words(dest: *mut u8, src: *const u8, n: usize) {
|
||||
|
||||
/// `n` is in units of bytes, but must be a multiple of the word size and must not be 0.
|
||||
/// `src` *must not* be `usize`-aligned.
|
||||
#[cfg(not(feature = "mem-unaligned"))]
|
||||
#[cfg(not(mem_unaligned))]
|
||||
#[inline(always)]
|
||||
unsafe fn copy_forward_misaligned_words(dest: *mut u8, src: *const u8, n: usize) {
|
||||
debug_assert!(n > 0 && n % WORD_SIZE == 0);
|
||||
@@ -185,7 +185,7 @@ unsafe fn copy_forward_misaligned_words(dest: *mut u8, src: *const u8, n: usize)
|
||||
|
||||
/// `n` is in units of bytes, but must be a multiple of the word size and must not be 0.
|
||||
/// `src` *must not* be `usize`-aligned.
|
||||
#[cfg(feature = "mem-unaligned")]
|
||||
#[cfg(mem_unaligned)]
|
||||
#[inline(always)]
|
||||
unsafe fn copy_forward_misaligned_words(dest: *mut u8, src: *const u8, n: usize) {
|
||||
let mut dest_usize = dest as *mut usize;
|
||||
@@ -252,7 +252,7 @@ unsafe fn copy_backward_aligned_words(dest: *mut u8, src: *const u8, n: usize) {
|
||||
|
||||
/// `n` is in units of bytes, but must be a multiple of the word size and must not be 0.
|
||||
/// `src` *must not* be `usize`-aligned.
|
||||
#[cfg(not(feature = "mem-unaligned"))]
|
||||
#[cfg(not(mem_unaligned))]
|
||||
#[inline(always)]
|
||||
unsafe fn copy_backward_misaligned_words(dest: *mut u8, src: *const u8, n: usize) {
|
||||
debug_assert!(n > 0 && n % WORD_SIZE == 0);
|
||||
@@ -301,7 +301,7 @@ unsafe fn copy_backward_misaligned_words(dest: *mut u8, src: *const u8, n: usize
|
||||
|
||||
/// `n` is in units of bytes, but must be a multiple of the word size and must not be 0.
|
||||
/// `src` *must not* be `usize`-aligned.
|
||||
#[cfg(feature = "mem-unaligned")]
|
||||
#[cfg(mem_unaligned)]
|
||||
#[inline(always)]
|
||||
unsafe fn copy_backward_misaligned_words(dest: *mut u8, src: *const u8, n: usize) {
|
||||
let mut dest_usize = dest as *mut usize;
|
||||
|
||||
@@ -4,10 +4,7 @@
|
||||
#![allow(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
// memcpy/memmove/memset have optimized implementations on some architectures
|
||||
#[cfg_attr(
|
||||
all(not(feature = "no-asm"), target_arch = "x86_64"),
|
||||
path = "x86_64.rs"
|
||||
)]
|
||||
#[cfg_attr(all(feature = "arch", target_arch = "x86_64"), path = "x86_64.rs")]
|
||||
mod impls;
|
||||
|
||||
intrinsics! {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user