Skip to content

Commit f0a751d

Browse files
committed
std_detect: support detecting more features on aarch64 Windows
Wire IsProcessorFeaturePresent for the PF_ARM_* constants exposed in Windows SDK 26100 (Win11 24H2): fp16 PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE (67) i8mm PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE (66) bf16 PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE (68) sha3 PF_ARM_SHA3 (64) AND PF_ARM_SHA512 (65) lse2 PF_ARM_LSE2_AVAILABLE (62) f32mm PF_ARM_SVE_F32MM_INSTRUCTIONS_AVAILABLE (58) f64mm PF_ARM_SVE_F64MM_INSTRUCTIONS_AVAILABLE (59) Also derive `rdm` from FEAT_DotProd. There is no PF_ARM_RDM_* constant; FEAT_DotProd is an optional v8.2-A feature only present on cores that implement at least v8.1-A, and v8.1-A with AdvSIMD mandates FEAT_RDM (Arm ARM K.a §D17.2.91). AdvSIMD is universal on Windows-on-ARM. See PR description for full rationale and .NET 10 precedent. All eight feature names have been stable in `is_aarch64_feature_detected!` on Linux/Darwin/BSD since Rust 1.60.
1 parent ca9a134 commit f0a751d

2 files changed

Lines changed: 61 additions & 5 deletions

File tree

library/std_detect/src/detect/os/windows/aarch64.rs

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,14 @@ pub(crate) fn detect_features() -> cache::Initializer {
3131
const PF_ARM_SVE_SHA3_INSTRUCTIONS_AVAILABLE: u32 = 55;
3232
const PF_ARM_SVE_SM4_INSTRUCTIONS_AVAILABLE: u32 = 56;
3333
// const PF_ARM_SVE_I8MM_INSTRUCTIONS_AVAILABLE: u32 = 57;
34-
// const PF_ARM_SVE_F32MM_INSTRUCTIONS_AVAILABLE: u32 = 58;
35-
// const PF_ARM_SVE_F64MM_INSTRUCTIONS_AVAILABLE: u32 = 59;
34+
const PF_ARM_SVE_F32MM_INSTRUCTIONS_AVAILABLE: u32 = 58;
35+
const PF_ARM_SVE_F64MM_INSTRUCTIONS_AVAILABLE: u32 = 59;
36+
const PF_ARM_LSE2_AVAILABLE: u32 = 62;
37+
const PF_ARM_SHA3_INSTRUCTIONS_AVAILABLE: u32 = 64;
38+
const PF_ARM_SHA512_INSTRUCTIONS_AVAILABLE: u32 = 65;
39+
const PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE: u32 = 66;
40+
const PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE: u32 = 67;
41+
const PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE: u32 = 68;
3642

3743
unsafe extern "system" {
3844
fn IsProcessorFeaturePresent(ProcessorFeature: DWORD) -> BOOL;
@@ -46,9 +52,11 @@ pub(crate) fn detect_features() -> cache::Initializer {
4652
}
4753
};
4854

49-
// Some features may be supported on current CPU,
50-
// but no way to detect it by OS API.
51-
// Also, we require unsafe block for the extern "system" calls.
55+
// Some features may be supported on the current CPU but have no
56+
// detection path through the Win32 API; those report `false`.
57+
// SAFETY: `IsProcessorFeaturePresent` is a Win32 entry point taking a
58+
// `DWORD` by value and returning a `BOOL`. No pointer parameters,
59+
// no out-parameters, no thread-safety constraints.
5260
unsafe {
5361
enable_feature(
5462
Feature::fp,
@@ -112,6 +120,46 @@ pub(crate) fn detect_features() -> cache::Initializer {
112120
Feature::sve2_sm4,
113121
IsProcessorFeaturePresent(PF_ARM_SVE_SM4_INSTRUCTIONS_AVAILABLE) != FALSE,
114122
);
123+
enable_feature(
124+
Feature::f32mm,
125+
IsProcessorFeaturePresent(PF_ARM_SVE_F32MM_INSTRUCTIONS_AVAILABLE) != FALSE,
126+
);
127+
enable_feature(
128+
Feature::f64mm,
129+
IsProcessorFeaturePresent(PF_ARM_SVE_F64MM_INSTRUCTIONS_AVAILABLE) != FALSE,
130+
);
131+
enable_feature(
132+
Feature::lse2,
133+
IsProcessorFeaturePresent(PF_ARM_LSE2_AVAILABLE) != FALSE,
134+
);
135+
enable_feature(
136+
Feature::fp16,
137+
IsProcessorFeaturePresent(PF_ARM_V82_FP16_INSTRUCTIONS_AVAILABLE) != FALSE,
138+
);
139+
enable_feature(
140+
Feature::i8mm,
141+
IsProcessorFeaturePresent(PF_ARM_V82_I8MM_INSTRUCTIONS_AVAILABLE) != FALSE,
142+
);
143+
enable_feature(
144+
Feature::bf16,
145+
IsProcessorFeaturePresent(PF_ARM_V86_BF16_INSTRUCTIONS_AVAILABLE) != FALSE,
146+
);
147+
// stdarch `sha3` is FEAT_SHA3 + FEAT_SHA512 together; Windows
148+
// exposes them as two separate flags.
149+
enable_feature(
150+
Feature::sha3,
151+
IsProcessorFeaturePresent(PF_ARM_SHA3_INSTRUCTIONS_AVAILABLE) != FALSE
152+
&& IsProcessorFeaturePresent(PF_ARM_SHA512_INSTRUCTIONS_AVAILABLE) != FALSE,
153+
);
154+
// No PF_ARM_RDM_* constant exists. Derive FEAT_RDM from FEAT_DotProd:
155+
// DotProd is an optional v8.2-A feature only present on cores that
156+
// implement at least v8.1-A; v8.1-A with AdvSIMD mandates FEAT_RDM
157+
// (Arm ARM K.a §D17.2.91), and AdvSIMD is universal on Windows-on-ARM.
158+
// Same inference shipped in .NET 10 (dotnet/runtime PR 109493).
159+
enable_feature(
160+
Feature::rdm,
161+
IsProcessorFeaturePresent(PF_ARM_V82_DP_INSTRUCTIONS_AVAILABLE) != FALSE,
162+
);
115163
// PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE means aes, sha1, sha2 and
116164
// pmull support
117165
let crypto =

library/std_detect/tests/cpu-detection.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,22 @@ fn aarch64_linux() {
150150
fn aarch64_windows() {
151151
println!("asimd: {:?}", is_aarch64_feature_detected!("asimd"));
152152
println!("fp: {:?}", is_aarch64_feature_detected!("fp"));
153+
println!("fp16: {:?}", is_aarch64_feature_detected!("fp16"));
153154
println!("crc: {:?}", is_aarch64_feature_detected!("crc"));
154155
println!("lse: {:?}", is_aarch64_feature_detected!("lse"));
156+
println!("lse2: {:?}", is_aarch64_feature_detected!("lse2"));
157+
println!("rdm: {:?}", is_aarch64_feature_detected!("rdm"));
155158
println!("dotprod: {:?}", is_aarch64_feature_detected!("dotprod"));
159+
println!("i8mm: {:?}", is_aarch64_feature_detected!("i8mm"));
160+
println!("bf16: {:?}", is_aarch64_feature_detected!("bf16"));
156161
println!("jsconv: {:?}", is_aarch64_feature_detected!("jsconv"));
157162
println!("rcpc: {:?}", is_aarch64_feature_detected!("rcpc"));
158163
println!("aes: {:?}", is_aarch64_feature_detected!("aes"));
159164
println!("pmull: {:?}", is_aarch64_feature_detected!("pmull"));
160165
println!("sha2: {:?}", is_aarch64_feature_detected!("sha2"));
166+
println!("sha3: {:?}", is_aarch64_feature_detected!("sha3"));
167+
println!("f32mm: {:?}", is_aarch64_feature_detected!("f32mm"));
168+
println!("f64mm: {:?}", is_aarch64_feature_detected!("f64mm"));
161169
}
162170

163171
#[test]

0 commit comments

Comments
 (0)