Skip to content

Commit aa3fc33

Browse files
authored
Merge pull request #2050 from folkertdev/aarch64-rand
add ACLE random number generation intrinsics
2 parents 6bd468c + d6ffea0 commit aa3fc33

File tree

4 files changed

+69
-30
lines changed

4 files changed

+69
-30
lines changed

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::*;

crates/core_arch/src/aarch64/mte.rs

Lines changed: 16 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,35 +3,17 @@
33
//! [ACLE documentation](https://arm-software.github.io/acle/main/acle.html#markdown-toc-mte-intrinsics)
44
55
unsafe extern "unadjusted" {
6-
#[cfg_attr(
7-
any(target_arch = "aarch64", target_arch = "arm64ec"),
8-
link_name = "llvm.aarch64.irg"
9-
)]
6+
#[link_name = "llvm.aarch64.irg"]
107
fn irg_(ptr: *const (), exclude: i64) -> *const ();
11-
#[cfg_attr(
12-
any(target_arch = "aarch64", target_arch = "arm64ec"),
13-
link_name = "llvm.aarch64.gmi"
14-
)]
8+
#[link_name = "llvm.aarch64.gmi"]
159
fn gmi_(ptr: *const (), exclude: i64) -> i64;
16-
#[cfg_attr(
17-
any(target_arch = "aarch64", target_arch = "arm64ec"),
18-
link_name = "llvm.aarch64.ldg"
19-
)]
10+
#[link_name = "llvm.aarch64.ldg"]
2011
fn ldg_(ptr: *const (), tag_ptr: *const ()) -> *const ();
21-
#[cfg_attr(
22-
any(target_arch = "aarch64", target_arch = "arm64ec"),
23-
link_name = "llvm.aarch64.stg"
24-
)]
12+
#[link_name = "llvm.aarch64.stg"]
2513
fn stg_(tagged_ptr: *const (), addr_to_tag: *const ());
26-
#[cfg_attr(
27-
any(target_arch = "aarch64", target_arch = "arm64ec"),
28-
link_name = "llvm.aarch64.addg"
29-
)]
14+
#[link_name = "llvm.aarch64.addg"]
3015
fn addg_(ptr: *const (), value: i64) -> *const ();
31-
#[cfg_attr(
32-
any(target_arch = "aarch64", target_arch = "arm64ec"),
33-
link_name = "llvm.aarch64.subp"
34-
)]
16+
#[link_name = "llvm.aarch64.subp"]
3517
fn subp_(ptr_a: *const (), ptr_b: *const ()) -> i64;
3618
}
3719

@@ -127,42 +109,46 @@ mod test {
127109
use super::*;
128110
use stdarch_test::assert_instr;
129111

130-
#[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(irg))] // FIXME: MSVC `dumpbin` doesn't support MTE
112+
// Instruction tests are separate because the functions use generics.
113+
//
114+
// FIXME: As of 2026 MSVC `dumpbin` doesn't support MTE.
115+
116+
#[cfg_attr(not(target_env = "msvc"), assert_instr(irg))]
131117
#[allow(dead_code)]
132118
#[target_feature(enable = "mte")]
133119
unsafe fn test_arm_mte_create_random_tag(src: *const (), mask: u64) -> *const () {
134120
__arm_mte_create_random_tag(src, mask)
135121
}
136122

137-
#[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(addg))]
123+
#[cfg_attr(not(target_env = "msvc"), assert_instr(addg))]
138124
#[allow(dead_code)]
139125
#[target_feature(enable = "mte")]
140126
unsafe fn test_arm_mte_increment_tag(src: *const ()) -> *const () {
141127
__arm_mte_increment_tag::<1, _>(src)
142128
}
143129

144-
#[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(gmi))]
130+
#[cfg_attr(not(target_env = "msvc"), assert_instr(gmi))]
145131
#[allow(dead_code)]
146132
#[target_feature(enable = "mte")]
147133
unsafe fn test_arm_mte_exclude_tag(src: *const (), excluded: u64) -> u64 {
148134
__arm_mte_exclude_tag(src, excluded)
149135
}
150136

151-
#[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(stg))]
137+
#[cfg_attr(not(target_env = "msvc"), assert_instr(stg))]
152138
#[allow(dead_code)]
153139
#[target_feature(enable = "mte")]
154140
unsafe fn test_arm_mte_set_tag(src: *const ()) {
155141
__arm_mte_set_tag(src)
156142
}
157143

158-
#[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(ldg))]
144+
#[cfg_attr(not(target_env = "msvc"), assert_instr(ldg))]
159145
#[allow(dead_code)]
160146
#[target_feature(enable = "mte")]
161147
unsafe fn test_arm_mte_get_tag(src: *const ()) -> *const () {
162148
__arm_mte_get_tag(src)
163149
}
164150

165-
#[cfg_attr(all(test, not(target_env = "msvc")), assert_instr(subp))]
151+
#[cfg_attr(not(target_env = "msvc"), assert_instr(subp))]
166152
#[allow(dead_code)]
167153
#[target_feature(enable = "mte")]
168154
unsafe fn test_arm_mte_ptrdiff(a: *const (), b: *const ()) -> i64 {
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//! AArch64 Random Number intrinsics
2+
//!
3+
//! [ACLE documentation](https://arm-software.github.io/acle/main/acle.html#random-number-generation-intrinsics)
4+
5+
#[cfg(test)]
6+
use stdarch_test::assert_instr;
7+
8+
unsafe extern "unadjusted" {
9+
#[link_name = "llvm.aarch64.rndr"]
10+
fn rndr_() -> Tuple;
11+
12+
#[link_name = "llvm.aarch64.rndrrs"]
13+
fn rndrrs_() -> Tuple;
14+
}
15+
16+
#[repr(C)]
17+
struct Tuple {
18+
bits: u64,
19+
status: bool,
20+
}
21+
22+
/// Stores a 64-bit random number into the object pointed to by the argument and returns
23+
/// zero. If the implementation could not generate a random number within a reasonable
24+
/// period of time the object pointed to by the input is set to zero and a non-zero value
25+
/// is returned.
26+
#[inline]
27+
#[target_feature(enable = "rand")]
28+
#[cfg_attr(test, assert_instr(mrs))]
29+
#[unstable(feature = "stdarch_aarch64_rand", issue = "153514")]
30+
pub unsafe fn __rndr(value: *mut u64) -> i32 {
31+
let Tuple { bits, status } = rndr_();
32+
unsafe { *value = bits };
33+
status as i32
34+
}
35+
36+
/// Reseeds the random number generator. After that stores a 64-bit random number into
37+
/// the object pointed to by the argument and returns zero. If the implementation could
38+
/// not generate a random number within a reasonable period of time the object pointed
39+
/// to by the input is set to zero and a non-zero value is returned.
40+
#[inline]
41+
#[target_feature(enable = "rand")]
42+
#[cfg_attr(test, assert_instr(mrs))]
43+
#[unstable(feature = "stdarch_aarch64_rand", issue = "153514")]
44+
pub unsafe fn __rndrrs(value: *mut u64) -> i32 {
45+
let Tuple { bits, status } = rndrrs_();
46+
unsafe { *value = bits };
47+
status as i32
48+
}

crates/stdarch-verify/tests/arm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ fn verify_all_signatures() {
445445
&& !rust.file.ends_with("v7.rs\"")
446446
&& !rust.file.ends_with("v8.rs\"")
447447
&& !rust.file.ends_with("mte.rs\"")
448+
&& !rust.file.ends_with("rand.rs\"")
448449
&& !rust.file.ends_with("ex.rs\"")
449450
&& !skip_intrinsic_verify.contains(&rust.name)
450451
{

0 commit comments

Comments
 (0)