Skip to content

Commit c1d9d08

Browse files
eduardosmAmanieu
authored andcommitted
Implement ARM __ssat and __usat functions
1 parent c0257c1 commit c1d9d08

File tree

3 files changed

+61
-7
lines changed

3 files changed

+61
-7
lines changed

crates/core_arch/src/arm/mod.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@
1111
mod sat;
1212

1313
#[cfg(any(target_feature = "v6", doc))]
14-
// Remove warning because this module is currently empty.
15-
#[allow(unused_imports)]
14+
#[unstable(feature = "stdarch_arm_sat", issue = "none")]
1615
pub use self::sat::*;
1716

1817
// Supported arches: 5TE, 7E-M. See Section 10.1 of ACLE (e.g. QADD)

crates/core_arch/src/arm/sat.rs

Lines changed: 59 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,62 @@
11
//! # References:
22
//!
33
//! - Section 8.4 "Saturating intrinsics"
4-
//!
5-
//! Intrinsics that could live here:
6-
//!
7-
//! - __ssat
8-
//! - __usat
4+
5+
#[cfg(test)]
6+
use stdarch_test::assert_instr;
7+
8+
/// Saturates a 32-bit signed integer to a signed integer with a given
9+
/// bit width.
10+
#[unstable(feature = "stdarch_arm_sat", issue = "none")]
11+
#[inline]
12+
#[cfg_attr(test, assert_instr("ssat", WIDTH = 8))]
13+
#[rustc_legacy_const_generics(1)]
14+
pub unsafe fn __ssat<const WIDTH: u32>(x: i32) -> i32 {
15+
static_assert!(matches!(WIDTH, 1..=32));
16+
arm_ssat(x, WIDTH as i32)
17+
}
18+
19+
/// Saturates a 32-bit signed integer to an unsigned integer with a given
20+
/// bit width.
21+
#[unstable(feature = "stdarch_arm_sat", issue = "none")]
22+
#[inline]
23+
#[cfg_attr(test, assert_instr("usat", WIDTH = 8))]
24+
#[rustc_legacy_const_generics(1)]
25+
pub unsafe fn __usat<const WIDTH: u32>(x: i32) -> u32 {
26+
static_assert!(matches!(WIDTH, 1..=32));
27+
arm_usat(x, WIDTH as i32)
28+
}
29+
30+
extern "unadjusted" {
31+
#[link_name = "llvm.arm.ssat"]
32+
fn arm_ssat(x: i32, y: i32) -> i32;
33+
34+
#[link_name = "llvm.arm.usat"]
35+
fn arm_usat(x: i32, y: i32) -> u32;
36+
}
37+
38+
#[cfg(test)]
39+
mod tests {
40+
use super::*;
41+
use stdarch_test::simd_test;
42+
43+
#[test]
44+
fn test_ssat() {
45+
unsafe {
46+
assert_eq!(__ssat::<8>(1), 1);
47+
assert_eq!(__ssat::<8>(1000), 127);
48+
assert_eq!(__ssat::<8>(-1), -1);
49+
assert_eq!(__ssat::<8>(-1000), -128);
50+
}
51+
}
52+
53+
#[test]
54+
fn test_usat() {
55+
unsafe {
56+
assert_eq!(__usat::<8>(1), 1);
57+
assert_eq!(__usat::<8>(1000), 255);
58+
assert_eq!(__usat::<8>(-1), 0);
59+
assert_eq!(__usat::<8>(-1000), 0);
60+
}
61+
}
62+
}

crates/stdarch-verify/tests/arm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,7 @@ fn verify_all_signatures() {
449449
// TODO: we still need to verify these intrinsics or find a
450450
// reference for them, need to figure out where though!
451451
if !rust.file.ends_with("dsp.rs\"")
452+
&& !rust.file.ends_with("sat.rs\"")
452453
&& !rust.file.ends_with("simd32.rs\"")
453454
&& !rust.file.ends_with("v6.rs\"")
454455
&& !rust.file.ends_with("v7.rs\"")

0 commit comments

Comments
 (0)