|
7 | 7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
8 | 8 | // option. This file may not be copied, modified, or distributed |
9 | 9 | // except according to those terms. |
| 10 | +// pattern: Functional Core |
10 | 11 |
|
11 | 12 | use crate::default::{F32x4, I32x4, U32x4}; |
| 13 | +#[cfg(all(pf_rustc_nightly, target_arch = "aarch64"))] |
| 14 | +use crate::arm::{F32x2 as ArmF32x2, F32x4 as ArmF32x4}; |
12 | 15 | use crate::scalar::F32x4 as F32x4S; |
13 | 16 |
|
14 | 17 | // F32x4 |
@@ -37,7 +40,14 @@ fn test_f32x4_accessors_and_mutators() { |
37 | 40 | fn test_f32x4_basic_ops() { |
38 | 41 | let a = F32x4::new(1.0, 3.0, 5.0, 7.0); |
39 | 42 | let b = F32x4::new(2.0, 2.0, 6.0, 6.0); |
40 | | - assert_eq!(a.approx_recip(), F32x4::new(0.99975586, 0.333313, 0.19995117, 0.14282227)); |
| 43 | + let approx_recip = a.approx_recip(); |
| 44 | + for (lane, expected) in IntoIterator::into_iter([1.0, 1.0 / 3.0, 1.0 / 5.0, 1.0 / 7.0]).enumerate() { |
| 45 | + assert!( |
| 46 | + (approx_recip[lane] - expected).abs() <= 0.002, |
| 47 | + "lane {lane} reciprocal estimate {got} exceeded tolerance for {expected}", |
| 48 | + got = approx_recip[lane], |
| 49 | + ); |
| 50 | + } |
41 | 51 | assert_eq!(a.min(b), F32x4::new(1.0, 2.0, 5.0, 6.0)); |
42 | 52 | assert_eq!(a.max(b), F32x4::new(2.0, 3.0, 6.0, 7.0)); |
43 | 53 | let c = F32x4::new(-1.0, 1.3, -20.0, 3.6); |
@@ -393,6 +403,46 @@ fn test_i32x4_basic_ops() { |
393 | 403 | let a = I32x4::new(6, 29, -40, 2); |
394 | 404 | let b = I32x4::new(10, -5, 10, 46); |
395 | 405 | assert_eq!(a.min(b), I32x4::new(6, -5, -40, 2)); |
| 406 | + assert_eq!(a.max(b), I32x4::new(10, 29, 10, 46)); |
| 407 | +} |
| 408 | + |
| 409 | +#[test] |
| 410 | +fn test_i32x4_min_max_large_values() { |
| 411 | + let a = I32x4::new(16_777_217, -16_777_219, 2_000_000_001, -2_000_000_001); |
| 412 | + let b = I32x4::new(16_777_218, -16_777_218, 2_000_000_000, -1_999_999_999); |
| 413 | + assert_eq!(a.min(b), I32x4::new(16_777_217, -16_777_219, 2_000_000_000, -2_000_000_001)); |
| 414 | + assert_eq!(a.max(b), I32x4::new(16_777_218, -16_777_218, 2_000_000_001, -1_999_999_999)); |
| 415 | +} |
| 416 | + |
| 417 | +#[cfg(all(pf_rustc_nightly, target_arch = "aarch64"))] |
| 418 | +#[test] |
| 419 | +fn test_arm_float_min_max_nan_behavior() { |
| 420 | + let a2 = ArmF32x2::new(std::f32::NAN, 3.0); |
| 421 | + let b2 = ArmF32x2::new(2.0, std::f32::NAN); |
| 422 | + let min2 = a2.min(b2); |
| 423 | + let max2 = a2.max(b2); |
| 424 | + assert_eq!(min2[0], 2.0); |
| 425 | + assert_eq!(min2[1], 3.0); |
| 426 | + assert_eq!(max2[0], 2.0); |
| 427 | + assert_eq!(max2[1], 3.0); |
| 428 | + |
| 429 | + let c2 = ArmF32x2::new(std::f32::NAN, std::f32::NAN); |
| 430 | + let both_nan2 = c2.min(c2); |
| 431 | + assert!(both_nan2[0].is_nan()); |
| 432 | + assert!(both_nan2[1].is_nan()); |
| 433 | + |
| 434 | + let a4 = ArmF32x4::new(std::f32::NAN, 3.0, 5.0, std::f32::NAN); |
| 435 | + let b4 = ArmF32x4::new(2.0, std::f32::NAN, 6.0, std::f32::NAN); |
| 436 | + let min4 = a4.min(b4); |
| 437 | + let max4 = a4.max(b4); |
| 438 | + assert_eq!(min4[0], 2.0); |
| 439 | + assert_eq!(min4[1], 3.0); |
| 440 | + assert_eq!(min4[2], 5.0); |
| 441 | + assert!(min4[3].is_nan()); |
| 442 | + assert_eq!(max4[0], 2.0); |
| 443 | + assert_eq!(max4[1], 3.0); |
| 444 | + assert_eq!(max4[2], 6.0); |
| 445 | + assert!(max4[3].is_nan()); |
396 | 446 | } |
397 | 447 |
|
398 | 448 | #[test] |
|
0 commit comments