Rollup merge of #144974 - tgross35:update-builtins, r=tgross35
compiler-builtins subtree update
Subtree update of `compiler-builtins` to 87a66ec969.
Created using https://github.com/rust-lang/josh-sync.
r? ``@ghost``
This commit is contained in:
commit
0a1e0c65ec
161 changed files with 464 additions and 533 deletions
|
|
@ -34,7 +34,9 @@ jobs:
|
|||
- name: Fetch pull request ref
|
||||
run: git fetch origin "$GITHUB_REF:$GITHUB_REF"
|
||||
if: github.event_name == 'pull_request'
|
||||
- run: python3 ci/ci-util.py generate-matrix >> "$GITHUB_OUTPUT"
|
||||
- run: |
|
||||
set -eo pipefail # Needed to actually fail the job if ci-util fails
|
||||
python3 ci/ci-util.py generate-matrix | tee "$GITHUB_OUTPUT"
|
||||
id: script
|
||||
|
||||
test:
|
||||
|
|
@ -50,7 +52,6 @@ jobs:
|
|||
os: ubuntu-24.04-arm
|
||||
- target: aarch64-pc-windows-msvc
|
||||
os: windows-2025
|
||||
test_verbatim: 1
|
||||
build_only: 1
|
||||
- target: arm-unknown-linux-gnueabi
|
||||
os: ubuntu-24.04
|
||||
|
|
@ -70,8 +71,12 @@ jobs:
|
|||
os: ubuntu-24.04
|
||||
- target: powerpc64le-unknown-linux-gnu
|
||||
os: ubuntu-24.04
|
||||
- target: powerpc64le-unknown-linux-gnu
|
||||
os: ubuntu-24.04-ppc64le
|
||||
- target: riscv64gc-unknown-linux-gnu
|
||||
os: ubuntu-24.04
|
||||
- target: s390x-unknown-linux-gnu
|
||||
os: ubuntu-24.04-s390x
|
||||
- target: thumbv6m-none-eabi
|
||||
os: ubuntu-24.04
|
||||
- target: thumbv7em-none-eabi
|
||||
|
|
@ -88,10 +93,8 @@ jobs:
|
|||
os: macos-13
|
||||
- target: i686-pc-windows-msvc
|
||||
os: windows-2025
|
||||
test_verbatim: 1
|
||||
- target: x86_64-pc-windows-msvc
|
||||
os: windows-2025
|
||||
test_verbatim: 1
|
||||
- target: i686-pc-windows-gnu
|
||||
os: windows-2025
|
||||
channel: nightly-i686-gnu
|
||||
|
|
@ -102,11 +105,23 @@ jobs:
|
|||
needs: [calculate_vars]
|
||||
env:
|
||||
BUILD_ONLY: ${{ matrix.build_only }}
|
||||
TEST_VERBATIM: ${{ matrix.test_verbatim }}
|
||||
MAY_SKIP_LIBM_CI: ${{ needs.calculate_vars.outputs.may_skip_libm_ci }}
|
||||
steps:
|
||||
- name: Print $HOME
|
||||
shell: bash
|
||||
run: |
|
||||
set -x
|
||||
echo "${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
|
||||
- name: Install Rust (rustup)
|
||||
shell: bash
|
||||
|
|
@ -117,7 +132,12 @@ jobs:
|
|||
rustup update "$channel" --no-self-update
|
||||
rustup default "$channel"
|
||||
rustup target add "${{ matrix.target }}"
|
||||
|
||||
# Our scripts use nextest if possible. This is skipped on the native ppc
|
||||
# and s390x runners since install-action doesn't support them.
|
||||
- uses: taiki-e/install-action@nextest
|
||||
if: "!(matrix.os == 'ubuntu-24.04-ppc64le' || matrix.os == 'ubuntu-24.04-s390x')"
|
||||
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
key: ${{ matrix.target }}
|
||||
|
|
@ -144,7 +164,7 @@ jobs:
|
|||
shell: bash
|
||||
- run: echo "RUST_COMPILER_RT_ROOT=$(realpath ./compiler-rt)" >> "$GITHUB_ENV"
|
||||
shell: bash
|
||||
|
||||
|
||||
- name: Download musl source
|
||||
run: ./ci/update-musl.sh
|
||||
shell: bash
|
||||
|
|
@ -256,7 +276,7 @@ jobs:
|
|||
with:
|
||||
name: ${{ env.BASELINE_NAME }}
|
||||
path: ${{ env.BASELINE_NAME }}.tar.xz
|
||||
|
||||
|
||||
- name: Run wall time benchmarks
|
||||
run: |
|
||||
# Always use the same seed for benchmarks. Ideally we should switch to a
|
||||
|
|
@ -311,8 +331,8 @@ jobs:
|
|||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install stable `rustfmt`
|
||||
run: rustup set profile minimal && rustup default stable && rustup component add rustfmt
|
||||
- name: Install nightly `rustfmt`
|
||||
run: rustup set profile minimal && rustup default nightly && rustup component add rustfmt
|
||||
- run: cargo fmt -- --check
|
||||
|
||||
extensive:
|
||||
|
|
|
|||
|
|
@ -12,12 +12,13 @@ jobs:
|
|||
if: github.repository == 'rust-lang/compiler-builtins'
|
||||
uses: rust-lang/josh-sync/.github/workflows/rustc-pull.yml@main
|
||||
with:
|
||||
github-app-id: ${{ vars.APP_CLIENT_ID }}
|
||||
# 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-bot-email: "compiler-builtins-ci-bot@rust-lang.zulipchat.com"
|
||||
zulip-bot-email: "compiler-builtins-ci-bot@rust-lang.zulipchat.com"
|
||||
pr-base-branch: master
|
||||
branch-name: rustc-pull
|
||||
secrets:
|
||||
zulip-api-token: ${{ secrets.ZULIP_API_TOKEN }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
github-app-secret: ${{ secrets.APP_PRIVATE_KEY }}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,9 @@ default = ["compiler-builtins"]
|
|||
# implementations and also filling in unimplemented intrinsics
|
||||
c = ["dep:cc"]
|
||||
|
||||
# Workaround for the Cranelift codegen backend. Disables any implementations
|
||||
# which use inline assembly and fall back to pure Rust versions (if available).
|
||||
# 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 = []
|
||||
|
||||
# Workaround for codegen backends which haven't yet implemented `f16` and
|
||||
|
|
|
|||
|
|
@ -40,11 +40,7 @@ mod intrinsics {
|
|||
x as f64
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f16_enabled,
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(all(f16_enabled, f128_enabled))]
|
||||
pub fn extendhftf(x: f16) -> f128 {
|
||||
x as f128
|
||||
}
|
||||
|
|
@ -201,11 +197,7 @@ mod intrinsics {
|
|||
|
||||
/* f128 operations */
|
||||
|
||||
#[cfg(all(
|
||||
f16_enabled,
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(all(f16_enabled, f128_enabled))]
|
||||
pub fn trunctfhf(x: f128) -> f16 {
|
||||
x as f16
|
||||
}
|
||||
|
|
@ -220,50 +212,32 @@ mod intrinsics {
|
|||
x as f64
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
pub fn fixtfsi(x: f128) -> i32 {
|
||||
x as i32
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
pub fn fixtfdi(x: f128) -> i64 {
|
||||
x as i64
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
pub fn fixtfti(x: f128) -> i128 {
|
||||
x as i128
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
pub fn fixunstfsi(x: f128) -> u32 {
|
||||
x as u32
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
pub fn fixunstfdi(x: f128) -> u64 {
|
||||
x as u64
|
||||
}
|
||||
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
pub fn fixunstfti(x: f128) -> u128 {
|
||||
x as u128
|
||||
}
|
||||
|
|
@ -540,47 +514,25 @@ fn run() {
|
|||
bb(extendhfdf(bb(2.)));
|
||||
#[cfg(f16_enabled)]
|
||||
bb(extendhfsf(bb(2.)));
|
||||
#[cfg(all(
|
||||
f16_enabled,
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(all(f16_enabled, f128_enabled))]
|
||||
bb(extendhftf(bb(2.)));
|
||||
#[cfg(f128_enabled)]
|
||||
bb(extendsftf(bb(2.)));
|
||||
bb(fixdfti(bb(2.)));
|
||||
bb(fixsfti(bb(2.)));
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
bb(fixtfdi(bb(2.)));
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
bb(fixtfsi(bb(2.)));
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
bb(fixtfti(bb(2.)));
|
||||
bb(fixunsdfti(bb(2.)));
|
||||
bb(fixunssfti(bb(2.)));
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
bb(fixunstfdi(bb(2.)));
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
bb(fixunstfsi(bb(2.)));
|
||||
#[cfg(all(
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(f128_enabled)]
|
||||
bb(fixunstfti(bb(2.)));
|
||||
#[cfg(f128_enabled)]
|
||||
bb(floatditf(bb(2)));
|
||||
|
|
@ -616,11 +568,7 @@ fn run() {
|
|||
bb(truncsfhf(bb(2.)));
|
||||
#[cfg(f128_enabled)]
|
||||
bb(trunctfdf(bb(2.)));
|
||||
#[cfg(all(
|
||||
f16_enabled,
|
||||
f128_enabled,
|
||||
not(any(target_arch = "powerpc", target_arch = "powerpc64"))
|
||||
))]
|
||||
#[cfg(all(f16_enabled, f128_enabled))]
|
||||
bb(trunctfhf(bb(2.)));
|
||||
#[cfg(f128_enabled)]
|
||||
bb(trunctfsf(bb(2.)));
|
||||
|
|
|
|||
|
|
@ -365,7 +365,6 @@ float_bench! {
|
|||
|
||||
/* float -> unsigned int */
|
||||
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
float_bench! {
|
||||
name: conv_f32_u32,
|
||||
sig: (a: f32) -> u32,
|
||||
|
|
@ -387,7 +386,6 @@ float_bench! {
|
|||
],
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
float_bench! {
|
||||
name: conv_f32_u64,
|
||||
sig: (a: f32) -> u64,
|
||||
|
|
@ -409,7 +407,6 @@ float_bench! {
|
|||
],
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
float_bench! {
|
||||
name: conv_f32_u128,
|
||||
sig: (a: f32) -> u128,
|
||||
|
|
@ -505,7 +502,6 @@ float_bench! {
|
|||
|
||||
/* float -> signed int */
|
||||
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
float_bench! {
|
||||
name: conv_f32_i32,
|
||||
sig: (a: f32) -> i32,
|
||||
|
|
@ -527,7 +523,6 @@ float_bench! {
|
|||
],
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
float_bench! {
|
||||
name: conv_f32_i64,
|
||||
sig: (a: f32) -> i64,
|
||||
|
|
@ -549,7 +544,6 @@ float_bench! {
|
|||
],
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
float_bench! {
|
||||
name: conv_f32_i128,
|
||||
sig: (a: f32) -> i128,
|
||||
|
|
@ -666,9 +660,6 @@ pub fn float_conv() {
|
|||
conv_f64_i128(&mut criterion);
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
// FIXME: ppc64le has a sporadic overflow panic in the crate functions
|
||||
// <https://github.com/rust-lang/compiler-builtins/issues/617#issuecomment-2125914639>
|
||||
#[cfg(not(all(target_arch = "powerpc64", target_endian = "little")))]
|
||||
{
|
||||
conv_u32_f128(&mut criterion);
|
||||
conv_u64_f128(&mut criterion);
|
||||
|
|
|
|||
|
|
@ -110,9 +110,7 @@ float_bench! {
|
|||
pub fn float_extend() {
|
||||
let mut criterion = Criterion::default().configure_from_args();
|
||||
|
||||
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
{
|
||||
extend_f16_f32(&mut criterion);
|
||||
extend_f16_f64(&mut criterion);
|
||||
|
|
|
|||
|
|
@ -121,9 +121,7 @@ float_bench! {
|
|||
pub fn float_trunc() {
|
||||
let mut criterion = Criterion::default().configure_from_args();
|
||||
|
||||
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
{
|
||||
trunc_f32_f16(&mut criterion);
|
||||
trunc_f64_f16(&mut criterion);
|
||||
|
|
@ -133,11 +131,8 @@ pub fn float_trunc() {
|
|||
|
||||
#[cfg(f128_enabled)]
|
||||
{
|
||||
// FIXME(#655): `f16` tests disabled until we can bootstrap symbols
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
trunc_f128_f16(&mut criterion);
|
||||
|
||||
trunc_f128_f32(&mut criterion);
|
||||
trunc_f128_f64(&mut criterion);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,28 +17,14 @@ pub fn skip_sys_checks(test_name: &str) -> bool {
|
|||
"extend_f16_f32",
|
||||
"trunc_f32_f16",
|
||||
"trunc_f64_f16",
|
||||
// FIXME(#616): re-enable once fix is in nightly
|
||||
// <https://github.com/rust-lang/compiler-builtins/issues/616>
|
||||
"mul_f32",
|
||||
"mul_f64",
|
||||
];
|
||||
|
||||
// FIXME(f16_f128): error on LE ppc64. There are more tests that are cfg-ed out completely
|
||||
// in their benchmark modules due to runtime panics.
|
||||
// <https://github.com/rust-lang/compiler-builtins/issues/617#issuecomment-2125914639>
|
||||
const PPC64LE_SKIPPED: &[&str] = &["extend_f32_f128"];
|
||||
|
||||
// FIXME(f16_f128): system symbols have incorrect results
|
||||
// <https://github.com/rust-lang/compiler-builtins/issues/617#issuecomment-2125914639>
|
||||
const X86_NO_SSE_SKIPPED: &[&str] = &[
|
||||
"add_f128", "sub_f128", "mul_f128", "div_f128", "powi_f32", "powi_f64",
|
||||
];
|
||||
|
||||
// FIXME(f16_f128): Wide multiply carry bug in `compiler-rt`, re-enable when nightly no longer
|
||||
// uses `compiler-rt` version.
|
||||
// <https://github.com/llvm/llvm-project/issues/91840>
|
||||
const AARCH64_SKIPPED: &[&str] = &["mul_f128", "div_f128"];
|
||||
|
||||
// FIXME(llvm): system symbols have incorrect results on Windows
|
||||
// <https://github.com/rust-lang/compiler-builtins/issues/617#issuecomment-2121359807>
|
||||
const WINDOWS_SKIPPED: &[&str] = &[
|
||||
|
|
@ -57,19 +43,7 @@ pub fn skip_sys_checks(test_name: &str) -> bool {
|
|||
return true;
|
||||
}
|
||||
|
||||
if cfg!(all(target_arch = "powerpc64", target_endian = "little"))
|
||||
&& PPC64LE_SKIPPED.contains(&test_name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if cfg!(all(target_arch = "x86", not(target_feature = "sse")))
|
||||
&& X86_NO_SSE_SKIPPED.contains(&test_name)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if cfg!(target_arch = "aarch64") && AARCH64_SKIPPED.contains(&test_name) {
|
||||
if cfg!(x86_no_sse) && X86_NO_SSE_SKIPPED.contains(&test_name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ macro_rules! float_sum {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
|
||||
#[cfg(not(x86_no_sse))]
|
||||
mod float_addsub {
|
||||
use super::*;
|
||||
|
||||
|
|
@ -122,7 +122,7 @@ mod float_addsub {
|
|||
}
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
|
||||
#[cfg(not(x86_no_sse))]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
mod float_addsub_f128 {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -59,32 +59,28 @@ mod i_to_f {
|
|||
|| ((error_minus == error || error_plus == error)
|
||||
&& ((f0.to_bits() & 1) != 0))
|
||||
{
|
||||
if !cfg!(any(
|
||||
target_arch = "powerpc",
|
||||
target_arch = "powerpc64"
|
||||
)) {
|
||||
panic!(
|
||||
"incorrect rounding by {}({}): {}, ({}, {}, {}), errors ({}, {}, {})",
|
||||
stringify!($fn),
|
||||
x,
|
||||
f1.to_bits(),
|
||||
y_minus_ulp,
|
||||
y,
|
||||
y_plus_ulp,
|
||||
error_minus,
|
||||
error,
|
||||
error_plus,
|
||||
);
|
||||
}
|
||||
panic!(
|
||||
"incorrect rounding by {}({}): {}, ({}, {}, {}), errors ({}, {}, {})",
|
||||
stringify!($fn),
|
||||
x,
|
||||
f1.to_bits(),
|
||||
y_minus_ulp,
|
||||
y,
|
||||
y_plus_ulp,
|
||||
error_minus,
|
||||
error,
|
||||
error_plus,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Test against native conversion. We disable testing on all `x86` because of
|
||||
// rounding bugs with `i686`. `powerpc` also has the same rounding bug.
|
||||
// Test against native conversion.
|
||||
// FIXME(x86,ppc): the platform version has rounding bugs on i686 and
|
||||
// PowerPC64le (for PPC this only shows up in Docker, not the native runner).
|
||||
// https://github.com/rust-lang/compiler-builtins/pull/384#issuecomment-740413334
|
||||
if !Float::eq_repr(f0, f1) && !cfg!(any(
|
||||
target_arch = "x86",
|
||||
target_arch = "powerpc",
|
||||
target_arch = "powerpc64"
|
||||
all(target_arch = "powerpc64", target_endian = "little")
|
||||
)) {
|
||||
panic!(
|
||||
"{}({}): std: {:?}, builtins: {:?}",
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ macro_rules! float {
|
|||
};
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
|
||||
#[cfg(not(x86_no_sse))]
|
||||
mod float_div {
|
||||
use super::*;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#![allow(unused_macros)]
|
||||
#![cfg_attr(f128_enabled, feature(f128))]
|
||||
#![cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
|
||||
|
||||
#[cfg_attr(x86_no_sse, allow(unused))]
|
||||
use builtins_test::*;
|
||||
|
||||
// This is approximate because of issues related to
|
||||
|
|
@ -52,6 +52,7 @@ macro_rules! pow {
|
|||
};
|
||||
}
|
||||
|
||||
#[cfg(not(x86_no_sse))] // FIXME(i586): failure for powidf2
|
||||
pow! {
|
||||
f32, 1e-4, __powisf2, all();
|
||||
f64, 1e-12, __powidf2, all();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
#![feature(decl_macro)] // so we can use pub(super)
|
||||
#![feature(macro_metavar_expr_concat)]
|
||||
#![cfg(all(target_arch = "aarch64", target_os = "linux", not(feature = "no-asm")))]
|
||||
#![cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
|
||||
/// Translate a byte size to a Rust type.
|
||||
macro int_ty {
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ macro_rules! float_mul {
|
|||
};
|
||||
}
|
||||
|
||||
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
|
||||
#[cfg(not(x86_no_sse))]
|
||||
mod float_mul {
|
||||
use super::*;
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ mod float_mul {
|
|||
}
|
||||
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg(not(all(target_arch = "x86", not(target_feature = "sse"))))]
|
||||
#[cfg(not(x86_no_sse))]
|
||||
#[cfg(not(any(target_arch = "powerpc", target_arch = "powerpc64")))]
|
||||
mod float_mul_f128 {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -7,10 +7,12 @@ git history.
|
|||
|
||||
import json
|
||||
import os
|
||||
import pprint
|
||||
import re
|
||||
import subprocess as sp
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
from functools import cache
|
||||
from glob import glob
|
||||
from inspect import cleandoc
|
||||
from os import getenv
|
||||
|
|
@ -50,15 +52,6 @@ GIT = ["git", "-C", REPO_ROOT]
|
|||
DEFAULT_BRANCH = "master"
|
||||
WORKFLOW_NAME = "CI" # Workflow that generates the benchmark artifacts
|
||||
ARTIFACT_PREFIX = "baseline-icount*"
|
||||
# Place this in a PR body to skip regression checks (must be at the start of a line).
|
||||
REGRESSION_DIRECTIVE = "ci: allow-regressions"
|
||||
# Place this in a PR body to skip extensive tests
|
||||
SKIP_EXTENSIVE_DIRECTIVE = "ci: skip-extensive"
|
||||
# Place this in a PR body to allow running a large number of extensive tests. If not
|
||||
# set, this script will error out if a threshold is exceeded in order to avoid
|
||||
# accidentally spending huge amounts of CI time.
|
||||
ALLOW_MANY_EXTENSIVE_DIRECTIVE = "ci: allow-many-extensive"
|
||||
MANY_EXTENSIVE_THRESHOLD = 20
|
||||
|
||||
# Don't run exhaustive tests if these files change, even if they contaiin a function
|
||||
# definition.
|
||||
|
|
@ -70,7 +63,7 @@ IGNORE_FILES = [
|
|||
|
||||
# libm PR CI takes a long time and doesn't need to run unless relevant files have been
|
||||
# changed. Anything matching this regex pattern will trigger a run.
|
||||
TRIGGER_LIBM_PR_CI = ".*(libm|musl).*"
|
||||
TRIGGER_LIBM_CI_FILE_PAT = ".*(libm|musl).*"
|
||||
|
||||
TYPES = ["f16", "f32", "f64", "f128"]
|
||||
|
||||
|
|
@ -80,6 +73,54 @@ def eprint(*args, **kwargs):
|
|||
print(*args, file=sys.stderr, **kwargs)
|
||||
|
||||
|
||||
@dataclass(init=False)
|
||||
class PrCfg:
|
||||
"""Directives that we allow in the commit body to control test behavior.
|
||||
|
||||
These are of the form `ci: foo`, at the start of a line.
|
||||
"""
|
||||
|
||||
# Skip regression checks (must be at the start of a line).
|
||||
allow_regressions: bool = False
|
||||
# Don't run extensive tests
|
||||
skip_extensive: bool = False
|
||||
|
||||
# Allow running a large number of extensive tests. If not set, this script
|
||||
# will error out if a threshold is exceeded in order to avoid accidentally
|
||||
# spending huge amounts of CI time.
|
||||
allow_many_extensive: bool = False
|
||||
|
||||
# Max number of extensive tests to run by default
|
||||
MANY_EXTENSIVE_THRESHOLD: int = 20
|
||||
|
||||
# Run tests for `libm` that may otherwise be skipped due to no changed files.
|
||||
always_test_libm: bool = False
|
||||
|
||||
# String values of directive names
|
||||
DIR_ALLOW_REGRESSIONS: str = "allow-regressions"
|
||||
DIR_SKIP_EXTENSIVE: str = "skip-extensive"
|
||||
DIR_ALLOW_MANY_EXTENSIVE: str = "allow-many-extensive"
|
||||
DIR_TEST_LIBM: str = "test-libm"
|
||||
|
||||
def __init__(self, body: str):
|
||||
directives = re.finditer(r"^\s*ci:\s*(?P<dir_name>\S*)", body, re.MULTILINE)
|
||||
for dir in directives:
|
||||
name = dir.group("dir_name")
|
||||
if name == self.DIR_ALLOW_REGRESSIONS:
|
||||
self.allow_regressions = True
|
||||
elif name == self.DIR_SKIP_EXTENSIVE:
|
||||
self.skip_extensive = True
|
||||
elif name == self.DIR_ALLOW_MANY_EXTENSIVE:
|
||||
self.allow_many_extensive = True
|
||||
elif name == self.DIR_TEST_LIBM:
|
||||
self.always_test_libm = True
|
||||
else:
|
||||
eprint(f"Found unexpected directive `{name}`")
|
||||
exit(1)
|
||||
|
||||
pprint.pp(self)
|
||||
|
||||
|
||||
@dataclass
|
||||
class PrInfo:
|
||||
"""GitHub response for PR query"""
|
||||
|
|
@ -88,10 +129,21 @@ class PrInfo:
|
|||
commits: list[str]
|
||||
created_at: str
|
||||
number: int
|
||||
cfg: PrCfg
|
||||
|
||||
@classmethod
|
||||
def load(cls, pr_number: int | str) -> Self:
|
||||
"""For a given PR number, query the body and commit list"""
|
||||
def from_env(cls) -> Self | None:
|
||||
"""Create a PR object from the PR_NUMBER environment if set, `None` otherwise."""
|
||||
pr_env = os.environ.get("PR_NUMBER")
|
||||
if pr_env is not None and len(pr_env) > 0:
|
||||
return cls.from_pr(pr_env)
|
||||
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
@cache # Cache so we don't print info messages multiple times
|
||||
def from_pr(cls, pr_number: int | str) -> Self:
|
||||
"""For a given PR number, query the body and commit list."""
|
||||
pr_info = sp.check_output(
|
||||
[
|
||||
"gh",
|
||||
|
|
@ -104,13 +156,9 @@ class PrInfo:
|
|||
],
|
||||
text=True,
|
||||
)
|
||||
eprint("PR info:", json.dumps(pr_info, indent=4))
|
||||
return cls(**json.loads(pr_info))
|
||||
|
||||
def contains_directive(self, directive: str) -> bool:
|
||||
"""Return true if the provided directive is on a line in the PR body"""
|
||||
lines = self.body.splitlines()
|
||||
return any(line.startswith(directive) for line in lines)
|
||||
pr_json = json.loads(pr_info)
|
||||
eprint("PR info:", json.dumps(pr_json, indent=4))
|
||||
return cls(**json.loads(pr_info), cfg=PrCfg(pr_json["body"]))
|
||||
|
||||
|
||||
class FunctionDef(TypedDict):
|
||||
|
|
@ -207,26 +255,32 @@ class Context:
|
|||
"""If this is a PR and no libm files were changed, allow skipping libm
|
||||
jobs."""
|
||||
|
||||
if self.is_pr():
|
||||
return all(not re.match(TRIGGER_LIBM_PR_CI, str(f)) for f in self.changed)
|
||||
# Always run on merge CI
|
||||
if not self.is_pr():
|
||||
return False
|
||||
|
||||
return False
|
||||
pr = PrInfo.from_env()
|
||||
assert pr is not None, "Is a PR but couldn't load PrInfo"
|
||||
|
||||
# Allow opting in to libm tests
|
||||
if pr.cfg.always_test_libm:
|
||||
return False
|
||||
|
||||
# By default, run if there are any changed files matching the pattern
|
||||
return all(not re.match(TRIGGER_LIBM_CI_FILE_PAT, str(f)) for f in self.changed)
|
||||
|
||||
def emit_workflow_output(self):
|
||||
"""Create a JSON object a list items for each type's changed files, if any
|
||||
did change, and the routines that were affected by the change.
|
||||
"""
|
||||
|
||||
pr_number = os.environ.get("PR_NUMBER")
|
||||
skip_tests = False
|
||||
error_on_many_tests = False
|
||||
|
||||
if pr_number is not None and len(pr_number) > 0:
|
||||
pr = PrInfo.load(pr_number)
|
||||
skip_tests = pr.contains_directive(SKIP_EXTENSIVE_DIRECTIVE)
|
||||
error_on_many_tests = not pr.contains_directive(
|
||||
ALLOW_MANY_EXTENSIVE_DIRECTIVE
|
||||
)
|
||||
pr = PrInfo.from_env()
|
||||
if pr is not None:
|
||||
skip_tests = pr.cfg.skip_extensive
|
||||
error_on_many_tests = not pr.cfg.allow_many_extensive
|
||||
|
||||
if skip_tests:
|
||||
eprint("Skipping all extensive tests")
|
||||
|
|
@ -253,16 +307,14 @@ class Context:
|
|||
may_skip = str(self.may_skip_libm_ci()).lower()
|
||||
print(f"extensive_matrix={ext_matrix}")
|
||||
print(f"may_skip_libm_ci={may_skip}")
|
||||
eprint(f"extensive_matrix={ext_matrix}")
|
||||
eprint(f"may_skip_libm_ci={may_skip}")
|
||||
eprint(f"total extensive tests: {total_to_test}")
|
||||
|
||||
if error_on_many_tests and total_to_test > MANY_EXTENSIVE_THRESHOLD:
|
||||
if error_on_many_tests and total_to_test > PrCfg.MANY_EXTENSIVE_THRESHOLD:
|
||||
eprint(
|
||||
f"More than {MANY_EXTENSIVE_THRESHOLD} tests would be run; add"
|
||||
f" `{ALLOW_MANY_EXTENSIVE_DIRECTIVE}` to the PR body if this is"
|
||||
f"More than {PrCfg.MANY_EXTENSIVE_THRESHOLD} tests would be run; add"
|
||||
f" `{PrCfg.DIR_ALLOW_MANY_EXTENSIVE}` to the PR body if this is"
|
||||
" intentional. If this is refactoring that happens to touch a lot of"
|
||||
f" files, `{SKIP_EXTENSIVE_DIRECTIVE}` can be used instead."
|
||||
f" files, `{PrCfg.DIR_SKIP_EXTENSIVE}` can be used instead."
|
||||
)
|
||||
exit(1)
|
||||
|
||||
|
|
@ -371,8 +423,8 @@ def handle_bench_regressions(args: list[str]):
|
|||
eprint(USAGE)
|
||||
exit(1)
|
||||
|
||||
pr = PrInfo.load(pr_number)
|
||||
if pr.contains_directive(REGRESSION_DIRECTIVE):
|
||||
pr = PrInfo.from_pr(pr_number)
|
||||
if pr.cfg.allow_regressions:
|
||||
eprint("PR allows regressions")
|
||||
return
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
@ -12,6 +12,5 @@ ENV CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_LINKER="$TOOLCHAIN_PREFIX"gcc \
|
|||
CARGO_TARGET_POWERPC64LE_UNKNOWN_LINUX_GNU_RUNNER=qemu-ppc64le-static \
|
||||
AR_powerpc64le_unknown_linux_gnu="$TOOLCHAIN_PREFIX"ar \
|
||||
CC_powerpc64le_unknown_linux_gnu="$TOOLCHAIN_PREFIX"gcc \
|
||||
QEMU_CPU=POWER8 \
|
||||
QEMU_LD_PREFIX=/usr/powerpc64le-linux-gnu \
|
||||
RUST_TEST_THREADS=1
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG IMAGE=ubuntu:24.04
|
||||
ARG IMAGE=ubuntu:25.04
|
||||
FROM $IMAGE
|
||||
|
||||
RUN apt-get update && \
|
||||
|
|
|
|||
|
|
@ -97,7 +97,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:24.04 (or rustlang/rust:nightly).
|
||||
ubuntu:25.04 (or rustlang/rust:nightly).
|
||||
"
|
||||
exit
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -41,7 +41,10 @@ else
|
|||
"${test_builtins[@]}" --benches
|
||||
"${test_builtins[@]}" --benches --release
|
||||
|
||||
if [ "${TEST_VERBATIM:-}" = "1" ]; then
|
||||
# Validate that having a verbatim path for the target directory works
|
||||
# (trivial to regress using `/` in paths to build artifacts rather than
|
||||
# `Path::join`). MinGW does not currently support these paths.
|
||||
if [[ "$target" = *"windows"* ]] && [[ "$target" != *"gnu"* ]]; then
|
||||
verb_path=$(cmd.exe //C echo \\\\?\\%cd%\\builtins-test\\target2)
|
||||
"${test_builtins[@]}" --target-dir "$verb_path" --features c
|
||||
fi
|
||||
|
|
@ -161,7 +164,7 @@ else
|
|||
mflags+=(--workspace --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
|
||||
|
|
@ -204,7 +207,7 @@ else
|
|||
"${cmd[@]}" "$profile_flag" release-checked --features unstable-intrinsics --benches
|
||||
|
||||
# Ensure that the routines do not panic.
|
||||
#
|
||||
#
|
||||
# `--tests` must be passed because no-panic is only enabled as a dev
|
||||
# dependency. The `release-opt` profile must be used to enable LTO and a
|
||||
# single CGU.
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
set -eux
|
||||
|
||||
url=git://git.musl-libc.org/musl
|
||||
url=https://github.com/kraj/musl.git
|
||||
ref=c47ad25ea3b484e10326f933e927c0bc8cded3da
|
||||
dst=crates/musl-math-sys/musl
|
||||
|
||||
|
|
|
|||
|
|
@ -35,8 +35,9 @@ default = ["compiler-builtins"]
|
|||
# implementations and also filling in unimplemented intrinsics
|
||||
c = ["dep:cc"]
|
||||
|
||||
# Workaround for the Cranelift codegen backend. Disables any implementations
|
||||
# which use inline assembly and fall back to pure Rust versions (if available).
|
||||
# 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 = []
|
||||
|
||||
# Workaround for codegen backends which haven't yet implemented `f16` and
|
||||
|
|
|
|||
|
|
@ -106,13 +106,6 @@ fn configure_libm(target: &Target) {
|
|||
println!("cargo:rustc-cfg=optimizations_enabled");
|
||||
}
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
println!(
|
||||
"cargo:rustc-env=CFG_CARGO_FEATURES={:?}",
|
||||
target.cargo_features
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
// Configuration that is shared between `compiler_builtins` and `builtins_test`.
|
||||
|
||||
use std::process::{Command, Stdio};
|
||||
use std::{env, str};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
@ -35,26 +34,6 @@ impl Target {
|
|||
.map(|s| s.to_lowercase().replace("_", "-"))
|
||||
.collect();
|
||||
|
||||
// Query rustc for options that Cargo does not provide env for. The bootstrap hack is used
|
||||
// to get consistent output regardless of channel (`f16`/`f128` config options are hidden
|
||||
// on stable otherwise).
|
||||
let mut cmd = Command::new(env::var("RUSTC").unwrap());
|
||||
cmd.args(["--print=cfg", "--target", &triple])
|
||||
.env("RUSTC_BOOTSTRAP", "1")
|
||||
.stderr(Stdio::inherit());
|
||||
let out = cmd
|
||||
.output()
|
||||
.unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
|
||||
let rustc_cfg = str::from_utf8(&out.stdout).unwrap();
|
||||
|
||||
// If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe
|
||||
// choice and leave `f16` and `f128` disabled.
|
||||
let rustc_output_ok = out.status.success();
|
||||
let reliable_f128 =
|
||||
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128");
|
||||
let reliable_f16 =
|
||||
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16");
|
||||
|
||||
Self {
|
||||
triple,
|
||||
triple_split,
|
||||
|
|
@ -74,8 +53,10 @@ impl Target {
|
|||
.split(",")
|
||||
.map(ToOwned::to_owned)
|
||||
.collect(),
|
||||
reliable_f128,
|
||||
reliable_f16,
|
||||
// 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(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,6 +81,13 @@ pub fn configure_aliases(target: &Target) {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ use core::intrinsics;
|
|||
|
||||
intrinsics! {
|
||||
#[unsafe(naked)]
|
||||
#[cfg(all(target_os = "uefi", not(feature = "no-asm")))]
|
||||
#[cfg(target_os = "uefi")]
|
||||
pub unsafe extern "custom" fn __chkstk() {
|
||||
core::arch::naked_asm!(
|
||||
".p2align 2",
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![cfg(not(feature = "no-asm"))]
|
||||
|
||||
// Interfaces used by naked trampolines.
|
||||
// SAFETY: these are defined in compiler-builtins
|
||||
unsafe extern "C" {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#![cfg(not(feature = "no-asm"))]
|
||||
|
||||
use core::arch::global_asm;
|
||||
|
||||
global_asm!(include_str!("hexagon/func_macro.s"), options(raw));
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ pub mod arm;
|
|||
#[cfg(any(target_arch = "aarch64", target_arch = "arm64ec"))]
|
||||
pub mod aarch64;
|
||||
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux", not(feature = "no-asm"),))]
|
||||
#[cfg(all(target_arch = "aarch64", target_os = "linux"))]
|
||||
pub mod aarch64_linux;
|
||||
|
||||
#[cfg(all(
|
||||
|
|
|
|||
|
|
@ -44,8 +44,6 @@
|
|||
#![cfg(not(feature = "mangled-names"))]
|
||||
// Windows and Cygwin already has builtins to do this.
|
||||
#![cfg(not(any(windows, target_os = "cygwin")))]
|
||||
// All these builtins require assembly
|
||||
#![cfg(not(feature = "no-asm"))]
|
||||
// We only define stack probing for these architectures today.
|
||||
#![cfg(any(target_arch = "x86_64", target_arch = "x86"))]
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,7 @@ use core::intrinsics;
|
|||
|
||||
intrinsics! {
|
||||
#[unsafe(naked)]
|
||||
#[cfg(all(
|
||||
any(all(windows, target_env = "gnu"), target_os = "uefi"),
|
||||
not(feature = "no-asm")
|
||||
))]
|
||||
#[cfg(any(all(windows, target_env = "gnu"), target_os = "uefi"))]
|
||||
pub unsafe extern "custom" fn __chkstk() {
|
||||
core::arch::naked_asm!(
|
||||
"jmp {}", // Jump to __alloca since fallthrough may be unreliable"
|
||||
|
|
@ -21,10 +18,7 @@ intrinsics! {
|
|||
}
|
||||
|
||||
#[unsafe(naked)]
|
||||
#[cfg(all(
|
||||
any(all(windows, target_env = "gnu"), target_os = "uefi"),
|
||||
not(feature = "no-asm")
|
||||
))]
|
||||
#[cfg(any(all(windows, target_env = "gnu"), target_os = "uefi"))]
|
||||
pub unsafe extern "custom" fn _alloca() {
|
||||
// __chkstk and _alloca are the same function
|
||||
core::arch::naked_asm!(
|
||||
|
|
|
|||
|
|
@ -9,14 +9,7 @@ use core::intrinsics;
|
|||
|
||||
intrinsics! {
|
||||
#[unsafe(naked)]
|
||||
#[cfg(all(
|
||||
any(
|
||||
all(windows, target_env = "gnu"),
|
||||
target_os = "cygwin",
|
||||
target_os = "uefi"
|
||||
),
|
||||
not(feature = "no-asm")
|
||||
))]
|
||||
#[cfg(any(all(windows, target_env = "gnu"), target_os = "cygwin", target_os = "uefi"))]
|
||||
pub unsafe extern "custom" fn ___chkstk_ms() {
|
||||
core::arch::naked_asm!(
|
||||
"push %rcx",
|
||||
|
|
|
|||
|
|
@ -40,8 +40,6 @@ macro_rules! functions {
|
|||
) => {
|
||||
// Run a simple check to ensure we can link and call the function without crashing.
|
||||
#[test]
|
||||
// FIXME(#309): LE PPC crashes calling some musl functions
|
||||
#[cfg_attr(all(target_arch = "powerpc64", target_endian = "little"), ignore)]
|
||||
fn $name() {
|
||||
<fn($($aty),+) -> $rty>::check(super::$name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,7 @@ edition = "2024"
|
|||
publish = false
|
||||
|
||||
[dependencies]
|
||||
# FIXME: used as a git dependency since the latest release does not support wasm
|
||||
object = { git = "https://github.com/gimli-rs/object.git", rev = "013fac75da56a684377af4151b8164b78c1790e0" }
|
||||
object = "0.37.1"
|
||||
serde_json = "1.0.140"
|
||||
|
||||
[features]
|
||||
|
|
|
|||
|
|
@ -271,18 +271,6 @@ impl MaybeOverride<(f32,)> for SpecialCase {
|
|||
|
||||
impl MaybeOverride<(f64,)> for SpecialCase {
|
||||
fn check_float<F: Float>(input: (f64,), actual: F, expected: F, ctx: &CheckCtx) -> CheckAction {
|
||||
if cfg!(x86_no_sse)
|
||||
&& ctx.base_name == BaseName::Ceil
|
||||
&& ctx.basis == CheckBasis::Musl
|
||||
&& input.0 < 0.0
|
||||
&& input.0 > -1.0
|
||||
&& expected == F::ZERO
|
||||
&& actual == F::ZERO
|
||||
{
|
||||
// musl returns -0.0, we return +0.0
|
||||
return XFAIL("i586 ceil signed zero");
|
||||
}
|
||||
|
||||
if cfg!(x86_no_sse)
|
||||
&& (ctx.base_name == BaseName::Rint || ctx.base_name == BaseName::Roundeven)
|
||||
&& (expected - actual).abs() <= F::ONE
|
||||
|
|
@ -292,16 +280,6 @@ impl MaybeOverride<(f64,)> for SpecialCase {
|
|||
return XFAIL("i586 rint rounding mode");
|
||||
}
|
||||
|
||||
if cfg!(x86_no_sse)
|
||||
&& (ctx.fn_ident == Identifier::Ceil || ctx.fn_ident == Identifier::Floor)
|
||||
&& expected.eq_repr(F::NEG_ZERO)
|
||||
&& actual.eq_repr(F::ZERO)
|
||||
{
|
||||
// FIXME: the x87 implementations do not keep the distinction between -0.0 and 0.0.
|
||||
// See https://github.com/rust-lang/libm/pull/404#issuecomment-2572399955
|
||||
return XFAIL("i586 ceil/floor signed zero");
|
||||
}
|
||||
|
||||
if cfg!(x86_no_sse)
|
||||
&& (ctx.fn_ident == Identifier::Exp10 || ctx.fn_ident == Identifier::Exp2)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
// Configuration shared with both libm and libm-test
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
use std::process::{Command, Stdio};
|
||||
use std::{env, str};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(dead_code)]
|
||||
pub struct Config {
|
||||
pub manifest_dir: PathBuf,
|
||||
|
|
@ -33,26 +33,6 @@ impl Config {
|
|||
.map(|s| s.to_lowercase().replace("_", "-"))
|
||||
.collect();
|
||||
|
||||
// Query rustc for options that Cargo does not provide env for. The bootstrap hack is used
|
||||
// to get consistent output regardless of channel (`f16`/`f128` config options are hidden
|
||||
// on stable otherwise).
|
||||
let mut cmd = Command::new(env::var("RUSTC").unwrap());
|
||||
cmd.args(["--print=cfg", "--target", &target_triple])
|
||||
.env("RUSTC_BOOTSTRAP", "1")
|
||||
.stderr(Stdio::inherit());
|
||||
let out = cmd
|
||||
.output()
|
||||
.unwrap_or_else(|e| panic!("failed to run `{cmd:?}`: {e}"));
|
||||
let rustc_cfg = str::from_utf8(&out.stdout).unwrap();
|
||||
|
||||
// If we couldn't query `rustc` (e.g. a custom JSON target was used), make the safe
|
||||
// choice and leave `f16` and `f128` disabled.
|
||||
let rustc_output_ok = out.status.success();
|
||||
let reliable_f128 =
|
||||
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f128");
|
||||
let reliable_f16 =
|
||||
rustc_output_ok && rustc_cfg.lines().any(|l| l == "target_has_reliable_f16");
|
||||
|
||||
Self {
|
||||
target_triple,
|
||||
manifest_dir: PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()),
|
||||
|
|
@ -66,8 +46,10 @@ impl Config {
|
|||
target_string: env::var("TARGET").unwrap(),
|
||||
target_vendor: env::var("CARGO_CFG_TARGET_VENDOR").unwrap(),
|
||||
target_features,
|
||||
reliable_f128,
|
||||
reliable_f16,
|
||||
// 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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ fn r(z: f64) -> f64 {
|
|||
/// Computes the inverse cosine (arc cosine) of the input value.
|
||||
/// Arguments must be in the range -1 to 1.
|
||||
/// Returns values in radians, in the range of 0 to pi.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn acos(x: f64) -> f64 {
|
||||
let x1p_120f = f64::from_bits(0x3870000000000000); // 0x1p-120 === 2 ^ -120
|
||||
let z: f64;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ fn r(z: f32) -> f32 {
|
|||
/// Computes the inverse cosine (arc cosine) of the input value.
|
||||
/// Arguments must be in the range -1 to 1.
|
||||
/// Returns values in radians, in the range of 0 to pi.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn acosf(x: f32) -> f32 {
|
||||
let x1p_120 = f32::from_bits(0x03800000); // 0x1p-120 === 2 ^ (-120)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const LN2: f64 = 0.693147180559945309417232121458176568; /* 0x3fe62e42, 0xfefa3
|
|||
/// Calculates the inverse hyperbolic cosine of `x`.
|
||||
/// Is defined as `log(x + sqrt(x*x-1))`.
|
||||
/// `x` must be a number greater than or equal to 1.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn acosh(x: f64) -> f64 {
|
||||
let u = x.to_bits();
|
||||
let e = ((u >> 52) as usize) & 0x7ff;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const LN2: f32 = 0.693147180559945309417232121458176568;
|
|||
/// Calculates the inverse hyperbolic cosine of `x`.
|
||||
/// Is defined as `log(x + sqrt(x*x-1))`.
|
||||
/// `x` must be a number greater than or equal to 1.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn acoshf(x: f32) -> f32 {
|
||||
let u = x.to_bits();
|
||||
let a = u & 0x7fffffff;
|
||||
|
|
|
|||
|
|
@ -1,37 +1,62 @@
|
|||
//! Architecture-specific support for x86-32 without SSE2
|
||||
//!
|
||||
//! We use an alternative implementation on x86, because the
|
||||
//! main implementation fails with the x87 FPU used by
|
||||
//! debian i386, probably due to excess precision issues.
|
||||
//!
|
||||
//! See https://github.com/rust-lang/compiler-builtins/pull/976 for discussion on why these
|
||||
//! functions are implemented in this way.
|
||||
|
||||
use super::super::fabs;
|
||||
|
||||
/// Use an alternative implementation on x86, because the
|
||||
/// main implementation fails with the x87 FPU used by
|
||||
/// debian i386, probably due to excess precision issues.
|
||||
/// Basic implementation taken from https://github.com/rust-lang/libm/issues/219.
|
||||
pub fn ceil(x: f64) -> f64 {
|
||||
if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
|
||||
let truncated = x as i64 as f64;
|
||||
if truncated < x {
|
||||
return truncated + 1.0;
|
||||
} else {
|
||||
return truncated;
|
||||
}
|
||||
} else {
|
||||
return x;
|
||||
pub fn ceil(mut x: f64) -> f64 {
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"fld qword ptr [{x}]",
|
||||
// Save the FPU control word, using `x` as scratch space.
|
||||
"fstcw [{x}]",
|
||||
// Set rounding control to 0b10 (+∞).
|
||||
"mov word ptr [{x} + 2], 0x0b7f",
|
||||
"fldcw [{x} + 2]",
|
||||
// Round.
|
||||
"frndint",
|
||||
// Restore FPU control word.
|
||||
"fldcw [{x}]",
|
||||
// Save rounded value to memory.
|
||||
"fstp qword ptr [{x}]",
|
||||
x = in(reg) &mut x,
|
||||
// All the x87 FPU stack is used, all registers must be clobbered
|
||||
out("st(0)") _, out("st(1)") _,
|
||||
out("st(2)") _, out("st(3)") _,
|
||||
out("st(4)") _, out("st(5)") _,
|
||||
out("st(6)") _, out("st(7)") _,
|
||||
options(nostack),
|
||||
);
|
||||
}
|
||||
x
|
||||
}
|
||||
|
||||
/// Use an alternative implementation on x86, because the
|
||||
/// main implementation fails with the x87 FPU used by
|
||||
/// debian i386, probably due to excess precision issues.
|
||||
/// Basic implementation taken from https://github.com/rust-lang/libm/issues/219.
|
||||
pub fn floor(x: f64) -> f64 {
|
||||
if fabs(x).to_bits() < 4503599627370496.0_f64.to_bits() {
|
||||
let truncated = x as i64 as f64;
|
||||
if truncated > x {
|
||||
return truncated - 1.0;
|
||||
} else {
|
||||
return truncated;
|
||||
}
|
||||
} else {
|
||||
return x;
|
||||
pub fn floor(mut x: f64) -> f64 {
|
||||
unsafe {
|
||||
core::arch::asm!(
|
||||
"fld qword ptr [{x}]",
|
||||
// Save the FPU control word, using `x` as scratch space.
|
||||
"fstcw [{x}]",
|
||||
// Set rounding control to 0b01 (-∞).
|
||||
"mov word ptr [{x} + 2], 0x077f",
|
||||
"fldcw [{x} + 2]",
|
||||
// Round.
|
||||
"frndint",
|
||||
// Restore FPU control word.
|
||||
"fldcw [{x}]",
|
||||
// Save rounded value to memory.
|
||||
"fstp qword ptr [{x}]",
|
||||
x = in(reg) &mut x,
|
||||
// All the x87 FPU stack is used, all registers must be clobbered
|
||||
out("st(0)") _, out("st(1)") _,
|
||||
out("st(2)") _, out("st(3)") _,
|
||||
out("st(4)") _, out("st(5)") _,
|
||||
out("st(6)") _, out("st(7)") _,
|
||||
options(nostack),
|
||||
);
|
||||
}
|
||||
x
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ fn comp_r(z: f64) -> f64 {
|
|||
/// Computes the inverse sine (arc sine) of the argument `x`.
|
||||
/// Arguments to asin must be in the range -1 to 1.
|
||||
/// Returns values in radians, in the range of -pi/2 to pi/2.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn asin(mut x: f64) -> f64 {
|
||||
let z: f64;
|
||||
let r: f64;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ fn r(z: f32) -> f32 {
|
|||
/// Computes the inverse sine (arc sine) of the argument `x`.
|
||||
/// Arguments to asin must be in the range -1 to 1.
|
||||
/// Returns values in radians, in the range of -pi/2 to pi/2.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn asinf(mut x: f32) -> f32 {
|
||||
let x1p_120 = f64::from_bits(0x3870000000000000); // 0x1p-120 === 2 ^ (-120)
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const LN2: f64 = 0.693147180559945309417232121458176568; /* 0x3fe62e42, 0xfefa3
|
|||
///
|
||||
/// Calculates the inverse hyperbolic sine of `x`.
|
||||
/// Is defined as `sgn(x)*log(|x|+sqrt(x*x+1))`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn asinh(mut x: f64) -> f64 {
|
||||
let mut u = x.to_bits();
|
||||
let e = ((u >> 52) as usize) & 0x7ff;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const LN2: f32 = 0.693147180559945309417232121458176568;
|
|||
///
|
||||
/// Calculates the inverse hyperbolic sine of `x`.
|
||||
/// Is defined as `sgn(x)*log(|x|+sqrt(x*x+1))`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn asinhf(mut x: f32) -> f32 {
|
||||
let u = x.to_bits();
|
||||
let i = u & 0x7fffffff;
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ const AT: [f64; 11] = [
|
|||
///
|
||||
/// Computes the inverse tangent (arc tangent) of the input value.
|
||||
/// Returns a value in radians, in the range of -pi/2 to pi/2.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn atan(x: f64) -> f64 {
|
||||
let mut x = x;
|
||||
let mut ix = (x.to_bits() >> 32) as u32;
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ const PI_LO: f64 = 1.2246467991473531772E-16; /* 0x3CA1A626, 0x33145C07 */
|
|||
/// Computes the inverse tangent (arc tangent) of `y/x`.
|
||||
/// Produces the correct result even for angles near pi/2 or -pi/2 (that is, when `x` is near 0).
|
||||
/// Returns a value in radians, in the range of -pi to pi.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn atan2(y: f64, x: f64) -> f64 {
|
||||
if x.is_nan() || y.is_nan() {
|
||||
return x + y;
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ const PI_LO: f32 = -8.7422776573e-08; /* 0xb3bbbd2e */
|
|||
/// Computes the inverse tangent (arc tangent) of `y/x`.
|
||||
/// Produces the correct result even for angles near pi/2 or -pi/2 (that is, when `x` is near 0).
|
||||
/// Returns a value in radians, in the range of -pi to pi.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn atan2f(y: f32, x: f32) -> f32 {
|
||||
if x.is_nan() || y.is_nan() {
|
||||
return x + y;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ const A_T: [f32; 5] = [
|
|||
///
|
||||
/// Computes the inverse tangent (arc tangent) of the input value.
|
||||
/// Returns a value in radians, in the range of -pi/2 to pi/2.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn atanf(mut x: f32) -> f32 {
|
||||
let x1p_120 = f32::from_bits(0x03800000); // 0x1p-120 === 2 ^ (-120)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use super::log1p;
|
|||
///
|
||||
/// Calculates the inverse hyperbolic tangent of `x`.
|
||||
/// Is defined as `log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn atanh(x: f64) -> f64 {
|
||||
let u = x.to_bits();
|
||||
let e = ((u >> 52) as usize) & 0x7ff;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use super::log1pf;
|
|||
///
|
||||
/// Calculates the inverse hyperbolic tangent of `x`.
|
||||
/// Is defined as `log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn atanhf(mut x: f32) -> f32 {
|
||||
let mut u = x.to_bits();
|
||||
let sign = (u >> 31) != 0;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use super::Float;
|
|||
use super::support::{FpResult, Round, cold_path};
|
||||
|
||||
/// Compute the cube root of the argument.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn cbrt(x: f64) -> f64 {
|
||||
cbrt_round(x, Round::Nearest).val
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ const B2: u32 = 642849266; /* B2 = (127-127.0/3-24/3-0.03306235651)*2**23 */
|
|||
/// Cube root (f32)
|
||||
///
|
||||
/// Computes the cube root of the argument.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn cbrtf(x: f32) -> f32 {
|
||||
let x1p24 = f32::from_bits(0x4b800000); // 0x1p24f === 2 ^ 24
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
///
|
||||
/// Finds the nearest integer greater than or equal to `x`.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn ceilf16(x: f16) -> f16 {
|
||||
super::generic::ceil(x)
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ pub fn ceilf16(x: f16) -> f16 {
|
|||
/// Ceil (f32)
|
||||
///
|
||||
/// Finds the nearest integer greater than or equal to `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn ceilf(x: f32) -> f32 {
|
||||
select_implementation! {
|
||||
name: ceilf,
|
||||
|
|
@ -24,7 +24,7 @@ pub fn ceilf(x: f32) -> f32 {
|
|||
/// Ceil (f64)
|
||||
///
|
||||
/// Finds the nearest integer greater than or equal to `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn ceil(x: f64) -> f64 {
|
||||
select_implementation! {
|
||||
name: ceil,
|
||||
|
|
@ -40,7 +40,7 @@ pub fn ceil(x: f64) -> f64 {
|
|||
///
|
||||
/// Finds the nearest integer greater than or equal to `x`.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn ceilf128(x: f128) -> f128 {
|
||||
super::generic::ceil(x)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
/// Constructs a number with the magnitude (absolute value) of its
|
||||
/// first argument, `x`, and the sign of its second argument, `y`.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn copysignf16(x: f16, y: f16) -> f16 {
|
||||
super::generic::copysign(x, y)
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ pub fn copysignf16(x: f16, y: f16) -> f16 {
|
|||
///
|
||||
/// Constructs a number with the magnitude (absolute value) of its
|
||||
/// first argument, `x`, and the sign of its second argument, `y`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn copysignf(x: f32, y: f32) -> f32 {
|
||||
super::generic::copysign(x, y)
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ pub fn copysignf(x: f32, y: f32) -> f32 {
|
|||
///
|
||||
/// Constructs a number with the magnitude (absolute value) of its
|
||||
/// first argument, `x`, and the sign of its second argument, `y`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn copysign(x: f64, y: f64) -> f64 {
|
||||
super::generic::copysign(x, y)
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ pub fn copysign(x: f64, y: f64) -> f64 {
|
|||
/// Constructs a number with the magnitude (absolute value) of its
|
||||
/// first argument, `x`, and the sign of its second argument, `y`.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn copysignf128(x: f128, y: f128) -> f128 {
|
||||
super::generic::copysign(x, y)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ use super::{k_cos, k_sin, rem_pio2};
|
|||
/// The cosine of `x` (f64).
|
||||
///
|
||||
/// `x` is specified in radians.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn cos(x: f64) -> f64 {
|
||||
let ix = (f64::to_bits(x) >> 32) as u32 & 0x7fffffff;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ const C4_PIO2: f64 = 4. * FRAC_PI_2; /* 0x401921FB, 0x54442D18 */
|
|||
/// The cosine of `x` (f32).
|
||||
///
|
||||
/// `x` is specified in radians.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn cosf(x: f32) -> f32 {
|
||||
let x64 = x as f64;
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use super::{exp, expm1, k_expo2};
|
|||
/// Computes the hyperbolic cosine of the argument x.
|
||||
/// Is defined as `(exp(x) + exp(-x))/2`
|
||||
/// Angles are specified in radians.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn cosh(mut x: f64) -> f64 {
|
||||
/* |x| */
|
||||
let mut ix = x.to_bits();
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ use super::{expf, expm1f, k_expo2f};
|
|||
/// Computes the hyperbolic cosine of the argument x.
|
||||
/// Is defined as `(exp(x) + exp(-x))/2`
|
||||
/// Angles are specified in radians.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn coshf(mut x: f32) -> f32 {
|
||||
let x1p120 = f32::from_bits(0x7b800000); // 0x1p120f === 2 ^ 120
|
||||
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ fn erfc2(ix: u32, mut x: f64) -> f64 {
|
|||
/// Calculates an approximation to the “error function”, which estimates
|
||||
/// the probability that an observation will fall within x standard
|
||||
/// deviations of the mean (assuming a normal distribution).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn erf(x: f64) -> f64 {
|
||||
let r: f64;
|
||||
let s: f64;
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ fn erfc2(mut ix: u32, mut x: f32) -> f32 {
|
|||
/// Calculates an approximation to the “error function”, which estimates
|
||||
/// the probability that an observation will fall within x standard
|
||||
/// deviations of the mean (assuming a normal distribution).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn erff(x: f32) -> f32 {
|
||||
let r: f32;
|
||||
let s: f32;
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ const P5: f64 = 4.13813679705723846039e-08; /* 0x3E663769, 0x72BEA4D0 */
|
|||
///
|
||||
/// Calculate the exponential of `x`, that is, *e* raised to the power `x`
|
||||
/// (where *e* is the base of the natural system of logarithms, approximately 2.71828).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn exp(mut x: f64) -> f64 {
|
||||
let x1p1023 = f64::from_bits(0x7fe0000000000000); // 0x1p1023 === 2 ^ 1023
|
||||
let x1p_149 = f64::from_bits(0x36a0000000000000); // 0x1p-149 === 2 ^ -149
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const P10: &[f64] = &[
|
|||
];
|
||||
|
||||
/// Calculates 10 raised to the power of `x` (f64).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn exp10(x: f64) -> f64 {
|
||||
let (mut y, n) = modf(x);
|
||||
let u: u64 = n.to_bits();
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ const P10: &[f32] = &[
|
|||
];
|
||||
|
||||
/// Calculates 10 raised to the power of `x` (f32).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn exp10f(x: f32) -> f32 {
|
||||
let (mut y, n) = modff(x);
|
||||
let u = n.to_bits();
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ static TBL: [u64; TBLSIZE * 2] = [
|
|||
/// Exponential, base 2 (f64)
|
||||
///
|
||||
/// Calculate `2^x`, that is, 2 raised to the power `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn exp2(mut x: f64) -> f64 {
|
||||
let redux = f64::from_bits(0x4338000000000000) / TBLSIZE as f64;
|
||||
let p1 = f64::from_bits(0x3fe62e42fefa39ef);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ static EXP2FT: [u64; TBLSIZE] = [
|
|||
/// Exponential, base 2 (f32)
|
||||
///
|
||||
/// Calculate `2^x`, that is, 2 raised to the power `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn exp2f(mut x: f32) -> f32 {
|
||||
let redux = f32::from_bits(0x4b400000) / TBLSIZE as f32;
|
||||
let p1 = f32::from_bits(0x3f317218);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ const P2: f32 = -2.7667332906e-3; /* -0xb55215.0p-32 */
|
|||
///
|
||||
/// Calculate the exponential of `x`, that is, *e* raised to the power `x`
|
||||
/// (where *e* is the base of the natural system of logarithms, approximately 2.71828).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn expf(mut x: f32) -> f32 {
|
||||
let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 127
|
||||
let x1p_126 = f32::from_bits(0x800000); // 0x1p-126f === 2 ^ -126 /*original 0x1p-149f ??????????? */
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ const Q5: f64 = -2.01099218183624371326e-07; /* BE8AFDB7 6E09C32D */
|
|||
/// system of logarithms, approximately 2.71828).
|
||||
/// The result is accurate even for small values of `x`,
|
||||
/// where using `exp(x)-1` would lose many significant digits.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn expm1(mut x: f64) -> f64 {
|
||||
let hi: f64;
|
||||
let lo: f64;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ const Q2: f32 = 1.5807170421e-3; /* 0xcf3010.0p-33 */
|
|||
/// system of logarithms, approximately 2.71828).
|
||||
/// The result is accurate even for small values of `x`,
|
||||
/// where using `exp(x)-1` would lose many significant digits.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn expm1f(mut x: f32) -> f32 {
|
||||
let x1p127 = f32::from_bits(0x7f000000); // 0x1p127f === 2 ^ 127
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use super::{combine_words, exp};
|
||||
|
||||
/* exp(x)/2 for x >= log(DBL_MAX), slightly better than 0.5*exp(x/2)*exp(x/2) */
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub(crate) fn expo2(x: f64) -> f64 {
|
||||
/* k is such that k*ln2 has minimal relative error and x - kln2 > log(DBL_MIN) */
|
||||
const K: i32 = 2043;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
/// Calculates the absolute value (magnitude) of the argument `x`,
|
||||
/// by direct manipulation of the bit representation of `x`.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fabsf16(x: f16) -> f16 {
|
||||
super::generic::fabs(x)
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ pub fn fabsf16(x: f16) -> f16 {
|
|||
///
|
||||
/// Calculates the absolute value (magnitude) of the argument `x`,
|
||||
/// by direct manipulation of the bit representation of `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fabsf(x: f32) -> f32 {
|
||||
select_implementation! {
|
||||
name: fabsf,
|
||||
|
|
@ -27,7 +27,7 @@ pub fn fabsf(x: f32) -> f32 {
|
|||
///
|
||||
/// Calculates the absolute value (magnitude) of the argument `x`,
|
||||
/// by direct manipulation of the bit representation of `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fabs(x: f64) -> f64 {
|
||||
select_implementation! {
|
||||
name: fabs,
|
||||
|
|
@ -43,7 +43,7 @@ pub fn fabs(x: f64) -> f64 {
|
|||
/// Calculates the absolute value (magnitude) of the argument `x`,
|
||||
/// by direct manipulation of the bit representation of `x`.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fabsf128(x: f128) -> f128 {
|
||||
super::generic::fabs(x)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
///
|
||||
/// A range error may occur.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fdimf16(x: f16, y: f16) -> f16 {
|
||||
super::generic::fdim(x, y)
|
||||
}
|
||||
|
|
@ -20,7 +20,7 @@ pub fn fdimf16(x: f16, y: f16) -> f16 {
|
|||
/// * NAN if either argument is NAN.
|
||||
///
|
||||
/// A range error may occur.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fdimf(x: f32, y: f32) -> f32 {
|
||||
super::generic::fdim(x, y)
|
||||
}
|
||||
|
|
@ -33,7 +33,7 @@ pub fn fdimf(x: f32, y: f32) -> f32 {
|
|||
/// * NAN if either argument is NAN.
|
||||
///
|
||||
/// A range error may occur.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fdim(x: f64, y: f64) -> f64 {
|
||||
super::generic::fdim(x, y)
|
||||
}
|
||||
|
|
@ -47,7 +47,7 @@ pub fn fdim(x: f64, y: f64) -> f64 {
|
|||
///
|
||||
/// A range error may occur.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fdimf128(x: f128, y: f128) -> f128 {
|
||||
super::generic::fdim(x, y)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
///
|
||||
/// Finds the nearest integer less than or equal to `x`.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn floorf16(x: f16) -> f16 {
|
||||
return super::generic::floor(x);
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ pub fn floorf16(x: f16) -> f16 {
|
|||
/// Floor (f64)
|
||||
///
|
||||
/// Finds the nearest integer less than or equal to `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn floor(x: f64) -> f64 {
|
||||
select_implementation! {
|
||||
name: floor,
|
||||
|
|
@ -25,7 +25,7 @@ pub fn floor(x: f64) -> f64 {
|
|||
/// Floor (f32)
|
||||
///
|
||||
/// Finds the nearest integer less than or equal to `x`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn floorf(x: f32) -> f32 {
|
||||
select_implementation! {
|
||||
name: floorf,
|
||||
|
|
@ -40,7 +40,7 @@ pub fn floorf(x: f32) -> f32 {
|
|||
///
|
||||
/// Finds the nearest integer less than or equal to `x`.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn floorf128(x: f128) -> f128 {
|
||||
return super::generic::floor(x);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ use crate::support::Round;
|
|||
// Placeholder so we can have `fmaf16` in the `Float` trait.
|
||||
#[allow(unused)]
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub(crate) fn fmaf16(_x: f16, _y: f16, _z: f16) -> f16 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
|
@ -15,7 +15,7 @@ pub(crate) fn fmaf16(_x: f16, _y: f16, _z: f16) -> f16 {
|
|||
/// Floating multiply add (f32)
|
||||
///
|
||||
/// Computes `(x*y)+z`, rounded as one ternary operation (i.e. calculated with infinite precision).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaf(x: f32, y: f32, z: f32) -> f32 {
|
||||
select_implementation! {
|
||||
name: fmaf,
|
||||
|
|
@ -32,7 +32,7 @@ pub fn fmaf(x: f32, y: f32, z: f32) -> f32 {
|
|||
/// Fused multiply add (f64)
|
||||
///
|
||||
/// Computes `(x*y)+z`, rounded as one ternary operation (i.e. calculated with infinite precision).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fma(x: f64, y: f64, z: f64) -> f64 {
|
||||
select_implementation! {
|
||||
name: fma,
|
||||
|
|
@ -50,7 +50,7 @@ pub fn fma(x: f64, y: f64, z: f64) -> f64 {
|
|||
///
|
||||
/// Computes `(x*y)+z`, rounded as one ternary operation (i.e. calculated with infinite precision).
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaf128(x: f128, y: f128, z: f128) -> f128 {
|
||||
generic::fma_round(x, y, z, Round::Nearest).val
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
/// This coincides with IEEE 754-2011 `minNum`. The result disregards signed zero (meaning if
|
||||
/// the inputs are -0.0 and +0.0, either may be returned).
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fminf16(x: f16, y: f16) -> f16 {
|
||||
super::generic::fmin(x, y)
|
||||
}
|
||||
|
|
@ -12,7 +12,7 @@ pub fn fminf16(x: f16, y: f16) -> f16 {
|
|||
///
|
||||
/// This coincides with IEEE 754-2011 `minNum`. The result disregards signed zero (meaning if
|
||||
/// the inputs are -0.0 and +0.0, either may be returned).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fminf(x: f32, y: f32) -> f32 {
|
||||
super::generic::fmin(x, y)
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ pub fn fminf(x: f32, y: f32) -> f32 {
|
|||
///
|
||||
/// This coincides with IEEE 754-2011 `minNum`. The result disregards signed zero (meaning if
|
||||
/// the inputs are -0.0 and +0.0, either may be returned).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmin(x: f64, y: f64) -> f64 {
|
||||
super::generic::fmin(x, y)
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ pub fn fmin(x: f64, y: f64) -> f64 {
|
|||
/// This coincides with IEEE 754-2011 `minNum`. The result disregards signed zero (meaning if
|
||||
/// the inputs are -0.0 and +0.0, either may be returned).
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fminf128(x: f128, y: f128) -> f128 {
|
||||
super::generic::fmin(x, y)
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ pub fn fminf128(x: f128, y: f128) -> f128 {
|
|||
/// This coincides with IEEE 754-2011 `maxNum`. The result disregards signed zero (meaning if
|
||||
/// the inputs are -0.0 and +0.0, either may be returned).
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaxf16(x: f16, y: f16) -> f16 {
|
||||
super::generic::fmax(x, y)
|
||||
}
|
||||
|
|
@ -50,7 +50,7 @@ pub fn fmaxf16(x: f16, y: f16) -> f16 {
|
|||
///
|
||||
/// This coincides with IEEE 754-2011 `maxNum`. The result disregards signed zero (meaning if
|
||||
/// the inputs are -0.0 and +0.0, either may be returned).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaxf(x: f32, y: f32) -> f32 {
|
||||
super::generic::fmax(x, y)
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ pub fn fmaxf(x: f32, y: f32) -> f32 {
|
|||
///
|
||||
/// This coincides with IEEE 754-2011 `maxNum`. The result disregards signed zero (meaning if
|
||||
/// the inputs are -0.0 and +0.0, either may be returned).
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmax(x: f64, y: f64) -> f64 {
|
||||
super::generic::fmax(x, y)
|
||||
}
|
||||
|
|
@ -69,7 +69,7 @@ pub fn fmax(x: f64, y: f64) -> f64 {
|
|||
/// This coincides with IEEE 754-2011 `maxNum`. The result disregards signed zero (meaning if
|
||||
/// the inputs are -0.0 and +0.0, either may be returned).
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaxf128(x: f128, y: f128) -> f128 {
|
||||
super::generic::fmax(x, y)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
///
|
||||
/// This coincides with IEEE 754-2019 `minimum`. The result orders -0.0 < 0.0.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fminimumf16(x: f16, y: f16) -> f16 {
|
||||
super::generic::fminimum(x, y)
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ pub fn fminimumf16(x: f16, y: f16) -> f16 {
|
|||
/// Return the lesser of two arguments or, if either argument is NaN, the other argument.
|
||||
///
|
||||
/// This coincides with IEEE 754-2019 `minimum`. The result orders -0.0 < 0.0.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fminimum(x: f64, y: f64) -> f64 {
|
||||
super::generic::fminimum(x, y)
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ pub fn fminimum(x: f64, y: f64) -> f64 {
|
|||
/// Return the lesser of two arguments or, if either argument is NaN, the other argument.
|
||||
///
|
||||
/// This coincides with IEEE 754-2019 `minimum`. The result orders -0.0 < 0.0.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fminimumf(x: f32, y: f32) -> f32 {
|
||||
super::generic::fminimum(x, y)
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ pub fn fminimumf(x: f32, y: f32) -> f32 {
|
|||
///
|
||||
/// This coincides with IEEE 754-2019 `minimum`. The result orders -0.0 < 0.0.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fminimumf128(x: f128, y: f128) -> f128 {
|
||||
super::generic::fminimum(x, y)
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ pub fn fminimumf128(x: f128, y: f128) -> f128 {
|
|||
///
|
||||
/// This coincides with IEEE 754-2019 `maximum`. The result orders -0.0 < 0.0.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaximumf16(x: f16, y: f16) -> f16 {
|
||||
super::generic::fmaximum(x, y)
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@ pub fn fmaximumf16(x: f16, y: f16) -> f16 {
|
|||
/// Return the greater of two arguments or, if either argument is NaN, the other argument.
|
||||
///
|
||||
/// This coincides with IEEE 754-2019 `maximum`. The result orders -0.0 < 0.0.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaximumf(x: f32, y: f32) -> f32 {
|
||||
super::generic::fmaximum(x, y)
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ pub fn fmaximumf(x: f32, y: f32) -> f32 {
|
|||
/// Return the greater of two arguments or, if either argument is NaN, the other argument.
|
||||
///
|
||||
/// This coincides with IEEE 754-2019 `maximum`. The result orders -0.0 < 0.0.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaximum(x: f64, y: f64) -> f64 {
|
||||
super::generic::fmaximum(x, y)
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ pub fn fmaximum(x: f64, y: f64) -> f64 {
|
|||
///
|
||||
/// This coincides with IEEE 754-2019 `maximum`. The result orders -0.0 < 0.0.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaximumf128(x: f128, y: f128) -> f128 {
|
||||
super::generic::fmaximum(x, y)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
///
|
||||
/// This coincides with IEEE 754-2019 `minimumNumber`. The result orders -0.0 < 0.0.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fminimum_numf16(x: f16, y: f16) -> f16 {
|
||||
super::generic::fminimum_num(x, y)
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ pub fn fminimum_numf16(x: f16, y: f16) -> f16 {
|
|||
/// Return the lesser of two arguments or, if either argument is NaN, NaN.
|
||||
///
|
||||
/// This coincides with IEEE 754-2019 `minimumNumber`. The result orders -0.0 < 0.0.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fminimum_numf(x: f32, y: f32) -> f32 {
|
||||
super::generic::fminimum_num(x, y)
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ pub fn fminimum_numf(x: f32, y: f32) -> f32 {
|
|||
/// Return the lesser of two arguments or, if either argument is NaN, NaN.
|
||||
///
|
||||
/// This coincides with IEEE 754-2019 `minimumNumber`. The result orders -0.0 < 0.0.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fminimum_num(x: f64, y: f64) -> f64 {
|
||||
super::generic::fminimum_num(x, y)
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ pub fn fminimum_num(x: f64, y: f64) -> f64 {
|
|||
///
|
||||
/// This coincides with IEEE 754-2019 `minimumNumber`. The result orders -0.0 < 0.0.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fminimum_numf128(x: f128, y: f128) -> f128 {
|
||||
super::generic::fminimum_num(x, y)
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ pub fn fminimum_numf128(x: f128, y: f128) -> f128 {
|
|||
///
|
||||
/// This coincides with IEEE 754-2019 `maximumNumber`. The result orders -0.0 < 0.0.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaximum_numf16(x: f16, y: f16) -> f16 {
|
||||
super::generic::fmaximum_num(x, y)
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@ pub fn fmaximum_numf16(x: f16, y: f16) -> f16 {
|
|||
/// Return the greater of two arguments or, if either argument is NaN, NaN.
|
||||
///
|
||||
/// This coincides with IEEE 754-2019 `maximumNumber`. The result orders -0.0 < 0.0.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaximum_numf(x: f32, y: f32) -> f32 {
|
||||
super::generic::fmaximum_num(x, y)
|
||||
}
|
||||
|
|
@ -52,7 +52,7 @@ pub fn fmaximum_numf(x: f32, y: f32) -> f32 {
|
|||
/// Return the greater of two arguments or, if either argument is NaN, NaN.
|
||||
///
|
||||
/// This coincides with IEEE 754-2019 `maximumNumber`. The result orders -0.0 < 0.0.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaximum_num(x: f64, y: f64) -> f64 {
|
||||
super::generic::fmaximum_num(x, y)
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ pub fn fmaximum_num(x: f64, y: f64) -> f64 {
|
|||
///
|
||||
/// This coincides with IEEE 754-2019 `maximumNumber`. The result orders -0.0 < 0.0.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmaximum_numf128(x: f128, y: f128) -> f128 {
|
||||
super::generic::fmaximum_num(x, y)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,25 +1,25 @@
|
|||
/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
|
||||
#[cfg(f16_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmodf16(x: f16, y: f16) -> f16 {
|
||||
super::generic::fmod(x, y)
|
||||
}
|
||||
|
||||
/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmodf(x: f32, y: f32) -> f32 {
|
||||
super::generic::fmod(x, y)
|
||||
}
|
||||
|
||||
/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmod(x: f64, y: f64) -> f64 {
|
||||
super::generic::fmod(x, y)
|
||||
}
|
||||
|
||||
/// Calculate the remainder of `x / y`, the precise result of `x - trunc(x / y) * y`.
|
||||
#[cfg(f128_enabled)]
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn fmodf128(x: f128, y: f128) -> f128 {
|
||||
super::generic::fmod(x, y)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn frexp(x: f64) -> (f64, i32) {
|
||||
let mut y = x.to_bits();
|
||||
let ee = ((y >> 52) & 0x7ff) as i32;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn frexpf(x: f32) -> (f32, i32) {
|
||||
let mut y = x.to_bits();
|
||||
let ee: i32 = ((y >> 23) & 0xff) as i32;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ fn sq(x: f64) -> (f64, f64) {
|
|||
(hi, lo)
|
||||
}
|
||||
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn hypot(mut x: f64, mut y: f64) -> f64 {
|
||||
let x1p700 = f64::from_bits(0x6bb0000000000000); // 0x1p700 === 2 ^ 700
|
||||
let x1p_700 = f64::from_bits(0x1430000000000000); // 0x1p-700 === 2 ^ -700
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use core::f32;
|
|||
|
||||
use super::sqrtf;
|
||||
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn hypotf(mut x: f32, mut y: f32) -> f32 {
|
||||
let x1p90 = f32::from_bits(0x6c800000); // 0x1p90f === 2 ^ 90
|
||||
let x1p_90 = f32::from_bits(0x12800000); // 0x1p-90f === 2 ^ -90
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const FP_ILOGBNAN: i32 = -1 - 0x7fffffff;
|
||||
const FP_ILOGB0: i32 = FP_ILOGBNAN;
|
||||
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn ilogb(x: f64) -> i32 {
|
||||
let mut i: u64 = x.to_bits();
|
||||
let e = ((i >> 52) & 0x7ff) as i32;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
const FP_ILOGBNAN: i32 = -1 - 0x7fffffff;
|
||||
const FP_ILOGB0: i32 = FP_ILOGBNAN;
|
||||
|
||||
#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
|
||||
#[cfg_attr(assert_no_panic, no_panic::no_panic)]
|
||||
pub fn ilogbf(x: f32) -> i32 {
|
||||
let mut i = x.to_bits();
|
||||
let e = ((i >> 23) & 0xff) as i32;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue