Skip to content

Commit 820d6d4

Browse files
committed
add ACLE random number generation intrinsics
1 parent 11d18f5 commit 820d6d4

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

crates/core_arch/src/aarch64/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ mod mte;
1717
#[unstable(feature = "stdarch_aarch64_mte", issue = "129010")]
1818
pub use self::mte::*;
1919

20+
mod rand;
21+
#[unstable(feature = "stdarch_aarch64_rand", issue = "153514")]
22+
pub use self::rand::*;
23+
2024
mod neon;
2125
#[stable(feature = "neon_intrinsics", since = "1.59.0")]
2226
pub use self::neon::*;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
//! AArch64 Random Number intrinsics
2+
//!
3+
//! [ACLE documentation](https://arm-software.github.io/acle/main/acle.html#random-number-generation-intrinsics)
4+
5+
unsafe extern "unadjusted" {
6+
#[cfg_attr(
7+
any(target_arch = "aarch64", target_arch = "arm64ec"),
8+
link_name = "llvm.aarch64.rndr"
9+
)]
10+
fn rndr_() -> PackedTuple<u64, bool>;
11+
12+
#[cfg_attr(
13+
any(target_arch = "aarch64", target_arch = "arm64ec"),
14+
link_name = "llvm.aarch64.rndrrs"
15+
)]
16+
fn rndrrs_() -> PackedTuple<u64, bool>;
17+
}
18+
19+
#[repr(C)]
20+
struct PackedTuple<T, U> {
21+
x: T,
22+
y: U,
23+
}
24+
25+
/// Stores a 64-bit random number into the object pointed to by the argument and returns
26+
/// zero. If the implementation could not generate a random number within a reasonable
27+
/// period of time the object pointed to by the input is set to zero and a non-zero value
28+
/// is returned.
29+
#[inline]
30+
#[target_feature(enable = "rand")]
31+
#[unstable(feature = "stdarch_aarch64_rand", issue = "153514")]
32+
pub unsafe fn __rndr(value: *mut u64) -> i32 {
33+
let PackedTuple { x: bits, y: ok } = rndr_();
34+
unsafe { *value = bits };
35+
ok as i32
36+
}
37+
38+
/// Reseeds the random number generator. After that stores a 64-bit random number into
39+
/// the object pointed to by the argument and returns zero. If the implementation could
40+
/// not generate a random number within a reasonable period of time the object pointed
41+
/// to by the input is set to zero and a non-zero value is returned.
42+
#[inline]
43+
#[target_feature(enable = "rand")]
44+
#[unstable(feature = "stdarch_aarch64_rand", issue = "153514")]
45+
pub unsafe fn __rndrrs(value: *mut u64) -> i32 {
46+
let PackedTuple { x: bits, y: ok } = rndrrs_();
47+
unsafe { *value = bits };
48+
ok as i32
49+
}
50+
51+
#[cfg(test)]
52+
mod test {
53+
use super::*;
54+
use stdarch_test::assert_instr;
55+
56+
#[cfg_attr(test, assert_instr(mrs))]
57+
#[allow(dead_code)]
58+
#[target_feature(enable = "rand")]
59+
unsafe fn test_rndr(value: &mut u64) -> i32 {
60+
__rndr(value)
61+
}
62+
63+
#[cfg_attr(test, assert_instr(mrs))]
64+
#[allow(dead_code)]
65+
#[target_feature(enable = "rand")]
66+
unsafe fn test_rndrrs(value: &mut u64) -> i32 {
67+
__rndrrs(value)
68+
}
69+
}

0 commit comments

Comments
 (0)