Skip to content

Commit c7e045a

Browse files
committed
std_detect: Split os/aarch64.rs' detect_features into reading and parsing
1 parent 55df1a8 commit c7e045a

File tree

1 file changed

+72
-63
lines changed

1 file changed

+72
-63
lines changed

crates/std_detect/src/detect/os/aarch64.rs

+72-63
Original file line numberDiff line numberDiff line change
@@ -23,77 +23,86 @@ use core::arch::asm;
2323
///
2424
/// This will cause SIGILL if the current OS is not trapping the mrs instruction.
2525
pub(crate) fn detect_features() -> cache::Initializer {
26-
let mut value = cache::Initializer::default();
26+
// ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0
27+
let aa64isar0: u64;
28+
unsafe {
29+
asm!(
30+
"mrs {}, ID_AA64ISAR0_EL1",
31+
out(reg) aa64isar0,
32+
options(pure, nomem, preserves_flags, nostack)
33+
);
34+
}
2735

28-
{
29-
let mut enable_feature = |f, enable| {
30-
if enable {
31-
value.set(f as u32);
32-
}
33-
};
36+
// ID_AA64ISAR1_EL1 - Instruction Set Attribute Register 1
37+
let aa64isar1: u64;
38+
unsafe {
39+
asm!(
40+
"mrs {}, ID_AA64ISAR1_EL1",
41+
out(reg) aa64isar1,
42+
options(pure, nomem, preserves_flags, nostack)
43+
);
44+
}
3445

35-
// ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0
36-
let aa64isar0: u64;
37-
unsafe {
38-
asm!(
39-
"mrs {}, ID_AA64ISAR0_EL1",
40-
out(reg) aa64isar0,
41-
options(pure, nomem, preserves_flags, nostack)
42-
);
43-
}
46+
// ID_AA64PFR0_EL1 - Processor Feature Register 0
47+
let aa64pfr0: u64;
48+
unsafe {
49+
asm!(
50+
"mrs {}, ID_AA64PFR0_EL1",
51+
out(reg) aa64pfr0,
52+
options(pure, nomem, preserves_flags, nostack)
53+
);
54+
}
55+
56+
parse_system_registers(aa64isar0, aa64isar1, aa64pfr0)
57+
}
4458

45-
enable_feature(Feature::pmull, bits_shift(aa64isar0, 7, 4) >= 2);
46-
enable_feature(Feature::tme, bits_shift(aa64isar0, 27, 24) == 1);
47-
enable_feature(Feature::lse, bits_shift(aa64isar0, 23, 20) >= 1);
48-
enable_feature(Feature::crc, bits_shift(aa64isar0, 19, 16) >= 1);
59+
pub(crate) fn parse_system_registers(
60+
aa64isar0: u64,
61+
aa64isar1: u64,
62+
aa64pfr0: u64,
63+
) -> cache::Initializer {
64+
let mut value = cache::Initializer::default();
4965

50-
// ID_AA64PFR0_EL1 - Processor Feature Register 0
51-
let aa64pfr0: u64;
52-
unsafe {
53-
asm!(
54-
"mrs {}, ID_AA64PFR0_EL1",
55-
out(reg) aa64pfr0,
56-
options(pure, nomem, preserves_flags, nostack)
57-
);
66+
let mut enable_feature = |f, enable| {
67+
if enable {
68+
value.set(f as u32);
5869
}
70+
};
5971

60-
let fp = bits_shift(aa64pfr0, 19, 16) < 0xF;
61-
let fphp = bits_shift(aa64pfr0, 19, 16) >= 1;
62-
let asimd = bits_shift(aa64pfr0, 23, 20) < 0xF;
63-
let asimdhp = bits_shift(aa64pfr0, 23, 20) >= 1;
64-
enable_feature(Feature::fp, fp);
65-
enable_feature(Feature::fp16, fphp);
66-
// SIMD support requires float support - if half-floats are
67-
// supported, it also requires half-float support:
68-
enable_feature(Feature::asimd, fp && asimd && (!fphp | asimdhp));
69-
// SIMD extensions require SIMD support:
70-
enable_feature(Feature::aes, asimd && bits_shift(aa64isar0, 7, 4) >= 1);
71-
let sha1 = bits_shift(aa64isar0, 11, 8) >= 1;
72-
let sha2 = bits_shift(aa64isar0, 15, 12) >= 1;
73-
enable_feature(Feature::sha2, asimd && sha1 && sha2);
74-
enable_feature(Feature::rdm, asimd && bits_shift(aa64isar0, 31, 28) >= 1);
75-
enable_feature(
76-
Feature::dotprod,
77-
asimd && bits_shift(aa64isar0, 47, 44) >= 1,
78-
);
79-
enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1);
72+
// ID_AA64ISAR0_EL1 - Instruction Set Attribute Register 0
73+
enable_feature(Feature::pmull, bits_shift(aa64isar0, 7, 4) >= 2);
74+
enable_feature(Feature::tme, bits_shift(aa64isar0, 27, 24) == 1);
75+
enable_feature(Feature::lse, bits_shift(aa64isar0, 23, 20) >= 1);
76+
enable_feature(Feature::crc, bits_shift(aa64isar0, 19, 16) >= 1);
8077

81-
// ID_AA64ISAR1_EL1 - Instruction Set Attribute Register 1
82-
let aa64isar1: u64;
83-
unsafe {
84-
asm!(
85-
"mrs {}, ID_AA64ISAR1_EL1",
86-
out(reg) aa64isar1,
87-
options(pure, nomem, preserves_flags, nostack)
88-
);
89-
}
78+
// ID_AA64PFR0_EL1 - Processor Feature Register 0
79+
let fp = bits_shift(aa64pfr0, 19, 16) < 0xF;
80+
let fphp = bits_shift(aa64pfr0, 19, 16) >= 1;
81+
let asimd = bits_shift(aa64pfr0, 23, 20) < 0xF;
82+
let asimdhp = bits_shift(aa64pfr0, 23, 20) >= 1;
83+
enable_feature(Feature::fp, fp);
84+
enable_feature(Feature::fp16, fphp);
85+
// SIMD support requires float support - if half-floats are
86+
// supported, it also requires half-float support:
87+
enable_feature(Feature::asimd, fp && asimd && (!fphp | asimdhp));
88+
// SIMD extensions require SIMD support:
89+
enable_feature(Feature::aes, asimd && bits_shift(aa64isar0, 7, 4) >= 1);
90+
let sha1 = bits_shift(aa64isar0, 11, 8) >= 1;
91+
let sha2 = bits_shift(aa64isar0, 15, 12) >= 1;
92+
enable_feature(Feature::sha2, asimd && sha1 && sha2);
93+
enable_feature(Feature::rdm, asimd && bits_shift(aa64isar0, 31, 28) >= 1);
94+
enable_feature(
95+
Feature::dotprod,
96+
asimd && bits_shift(aa64isar0, 47, 44) >= 1,
97+
);
98+
enable_feature(Feature::sve, asimd && bits_shift(aa64pfr0, 35, 32) >= 1);
9099

91-
// Check for either APA or API field
92-
enable_feature(Feature::paca, bits_shift(aa64isar1, 11, 4) >= 1);
93-
enable_feature(Feature::rcpc, bits_shift(aa64isar1, 23, 20) >= 1);
94-
// Check for either GPA or GPI field
95-
enable_feature(Feature::pacg, bits_shift(aa64isar1, 31, 24) >= 1);
96-
}
100+
// ID_AA64PFR0_EL1 - Processor Feature Register 0
101+
// Check for either APA or API field
102+
enable_feature(Feature::paca, bits_shift(aa64isar1, 11, 4) >= 1);
103+
enable_feature(Feature::rcpc, bits_shift(aa64isar1, 23, 20) >= 1);
104+
// Check for either GPA or GPI field
105+
enable_feature(Feature::pacg, bits_shift(aa64isar1, 31, 24) >= 1);
97106

98107
value
99108
}

0 commit comments

Comments
 (0)