Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ diff --git a/coretests/tests/lib.rs b/coretests/tests/lib.rs
index 1e336bf..35e6f54 100644
--- a/coretests/tests/lib.rs
+++ b/coretests/tests/lib.rs
@@ -2,4 +2,3 @@
@@ -2,7 +2,6 @@
// tidy-alphabetical-start
#![cfg_attr(any(target_arch = "powerpc", target_arch = "powerpc64"), feature(powerpc_ppcf128))]
#![cfg_attr(any(target_arch = "powerpc", target_arch = "powerpc64"), feature(stdarch_powerpc))]
#![cfg_attr(not(panic = "abort"), feature(reentrant_lock))]
-#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
#![feature(array_ptr_get)]
Expand Down
2 changes: 2 additions & 0 deletions library/coretests/tests/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// tidy-alphabetical-start
#![cfg_attr(any(target_arch = "powerpc", target_arch = "powerpc64"), feature(powerpc_ppcf128))]
#![cfg_attr(any(target_arch = "powerpc", target_arch = "powerpc64"), feature(stdarch_powerpc))]
#![cfg_attr(not(panic = "abort"), feature(reentrant_lock))]
#![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
#![feature(array_ptr_get)]
Expand Down
2 changes: 2 additions & 0 deletions library/coretests/tests/num/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ mod midpoint;
mod nan;
mod niche_types;
mod ops;
#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
mod ppcf128;
mod wrapping;

use floats::{assert_biteq, float_test};
Expand Down
172 changes: 172 additions & 0 deletions library/coretests/tests/num/ppcf128.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
#[cfg(target_arch = "powerpc")]
use core::arch::powerpc::ppcf128;
#[cfg(target_arch = "powerpc64")]
use core::arch::powerpc64::ppcf128;
use std::assert_matches;

const _: () = assert!(size_of::<ppcf128>() == 16);
const _: () = assert!(align_of::<ppcf128>() == 16);

#[test]
fn constants() {
assert_eq!(
ppcf128::MIN.to_le_bytes(),
[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, //
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0xfc,
]
);

assert_eq!(
ppcf128::MAX.to_le_bytes(),
[
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x7f, //
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x8f, 0x7c,
]
);

assert_eq!(
ppcf128::NAN.to_le_bytes(),
[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]
);

assert_eq!(
ppcf128::INFINITY.to_le_bytes(),
[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]
);

assert_eq!(
ppcf128::NEG_INFINITY.to_le_bytes(),
[
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
]
);
}

#[test]
fn impls() {
const ONE: ppcf128 = ppcf128::from_components(1.0, 0.0);
const NEGATIVE_ONE: ppcf128 = ppcf128::from_components(-1.0, 0.0);
const TWO: ppcf128 = ppcf128::from_components(2.0, 0.0);

assert_eq!(ONE, ONE);
assert_ne!(ONE, TWO);

assert!(ONE <= ONE);
assert!(ONE < TWO);
assert!(TWO > ONE);
assert!(TWO >= TWO);

assert!(NEGATIVE_ONE <= NEGATIVE_ONE);
assert!(NEGATIVE_ONE < ONE);
assert!(ONE > NEGATIVE_ONE);
assert!(ONE >= ONE);

const MAX: ppcf128 = ppcf128::MAX;
const ALMOST_MAX: ppcf128 = {
let (large, small) = MAX.to_components();
ppcf128::from_components(large, small.next_down())
};

assert!(ALMOST_MAX <= ALMOST_MAX);
assert!(ALMOST_MAX < MAX);
assert!(MAX > ALMOST_MAX);
assert!(MAX >= MAX);

assert!(ONE < ppcf128::INFINITY);
assert!(ONE > ppcf128::NEG_INFINITY);

assert_ne!(ONE, ppcf128::NAN);
assert_ne!(ppcf128::NAN, ppcf128::NAN);

assert_eq!(ppcf128::default().to_components(), (0.0, 0.0));
Comment thread
folkertdev marked this conversation as resolved.
}

macro_rules! assert_eq_normalized {
(($large:expr, $small:expr) ==> ($expected_large:expr, $expected_small:expr)) => {{
let (large, small) = ppcf128::from_components($large, $small).to_components();
let (expected_large, expected_small): (f64, f64) = ($expected_large, $expected_small);

if expected_large.is_nan() {
assert!(large.is_nan(), "expected NaN, got {large}");
} else {
assert_eq!(large, expected_large);
}

if expected_small.is_nan() {
assert!(small.is_nan(), "expected NaN, got {small}");
} else {
assert_eq!(small, expected_small);
}
}};
}

#[test]
fn normalize() {
// Already normalized.
assert_eq_normalized!((1.0, 0.0) ==> (1.0, 0.0));
assert_eq_normalized!((-1.0, 0.0) ==> (-1.0, 0.0));

// The value is normalized.
assert_eq_normalized!((1.0, 0.5) ==> (1.5, 0.0));
assert_eq_normalized!((-1.0, 0.5) ==> (-0.5, 0.0));
assert_eq_normalized!((0.0, 1.0) ==> (1.0, 0.0));
assert_eq_normalized!((0.0, -1.0) ==> (-1.0, 0.0));

let large = 2.0f64.powi(53);
assert_eq_normalized!((large, -(large - 1.0)) ==> (1.0, 0.0));

// Exact cancellation.
assert_eq_normalized!((1.0, -1.0) ==> (0.0, 0.0));
assert_eq_normalized!((-1.0, 1.0) ==> (0.0, 0.0));

// A component too small to affect the high part remains in the low part.
let half_ulp = f64::EPSILON / 2.0;
assert_eq_normalized!((1.0, half_ulp) ==> (1.0, half_ulp));
assert_eq_normalized!((-1.0, -half_ulp) ==> (-1.0, -half_ulp));

assert_eq_normalized!((1.0, -half_ulp) ==> (1.0 - half_ulp, 0.0));
assert_eq_normalized!((-1.0, half_ulp) ==> (-1.0 + half_ulp, 0.0));

// Rounding the sum produces a compensating low component.
let three_quarters_ulp = 3.0 * f64::EPSILON / 4.0;
assert_eq_normalized!(
(1.0, three_quarters_ulp) ==>
(1.0 + f64::EPSILON, -f64::EPSILON / 4.0)
);

// Normalization works across a large difference in exponent.
let large = 2.0f64.powi(100);
assert_eq_normalized!((1.0, large) ==> (large, 1.0));

// Infinity with a zero low component is already normalized.
assert_eq_normalized!((f64::INFINITY, 0.0) ==> (f64::INFINITY, 0.0));
assert_eq_normalized!((f64::NEG_INFINITY, 0.0) ==> (f64::NEG_INFINITY, 0.0));

// The small component of an infinity is normalized to zero.
assert_eq_normalized!((f64::INFINITY, 42.0) ==> (f64::INFINITY, 0.0));
assert_eq_normalized!((f64::NEG_INFINITY, 42.0) ==> (f64::NEG_INFINITY, 0.0));

// A finite high component combined with infinity normalizes to infinity.
assert_eq_normalized!((1.0, f64::INFINITY) ==> (f64::INFINITY, 0.0));
assert_eq_normalized!((1.0, f64::NEG_INFINITY) ==> (f64::NEG_INFINITY, 0.0));

// Opposite infinities produce NaN.
assert_eq_normalized!(
(f64::INFINITY, f64::NEG_INFINITY) ==>
(f64::NAN, 0.0)
);

assert_eq_normalized!((1.0, f64::NAN) ==> (f64::NAN, 0.0));
assert_eq_normalized!((f64::NAN, 1.0) ==> (f64::NAN, 1.0));

assert_matches!(ppcf128::checked_from_components(1.0, 0.0), Some(_));
assert_matches!(ppcf128::checked_from_components(0.0, 1.0), None);
}
12 changes: 8 additions & 4 deletions library/stdarch/crates/core_arch/src/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ pub mod arch {
/// Platform-specific intrinsics for the `PowerPC` platform.
///
/// See the [module documentation](../index.html) for more details.
#[cfg(any(target_arch = "powerpc", doc))]
#[cfg(any(target_arch = "powerpc", all(doc, not(doctest))))]
#[doc(cfg(target_arch = "powerpc"))]
#[unstable(feature = "stdarch_powerpc", issue = "111145")]
pub mod powerpc {
Expand All @@ -265,7 +265,7 @@ pub mod arch {
/// Platform-specific intrinsics for the `PowerPC64` platform.
///
/// See the [module documentation](../index.html) for more details.
#[cfg(any(target_arch = "powerpc64", doc))]
#[cfg(any(target_arch = "powerpc64", all(doc, not(doctest))))]
#[doc(cfg(target_arch = "powerpc64"))]
#[unstable(feature = "stdarch_powerpc", issue = "111145")]
pub mod powerpc64 {
Expand Down Expand Up @@ -368,11 +368,15 @@ mod wasm32;
#[doc(cfg(any(target_arch = "mips", target_arch = "mips64")))]
mod mips;

#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64", doc))]
#[cfg(any(
target_arch = "powerpc",
target_arch = "powerpc64",
all(doc, not(doctest))
))]
#[doc(cfg(any(target_arch = "powerpc", target_arch = "powerpc64")))]
mod powerpc;

#[cfg(any(target_arch = "powerpc64", doc))]
#[cfg(any(target_arch = "powerpc64", all(doc, not(doctest))))]
#[doc(cfg(target_arch = "powerpc64"))]
mod powerpc64;

Expand Down
Loading
Loading