@@ -23,77 +23,86 @@ use core::arch::asm;
23
23
///
24
24
/// This will cause SIGILL if the current OS is not trapping the mrs instruction.
25
25
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
+ }
27
35
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
+ }
34
45
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
+ }
44
58
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 ( ) ;
49
65
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 ) ;
58
69
}
70
+ } ;
59
71
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 ) ;
80
77
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 ) ;
90
99
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 ) ;
97
106
98
107
value
99
108
}
0 commit comments