@@ -44,12 +44,20 @@ include!("common.rs");
44
44
struct AA64Reg {
45
45
aa64isar0 : u64 ,
46
46
aa64isar1 : u64 ,
47
+ #[ cfg( test) ]
48
+ aa64isar3 : u64 ,
47
49
aa64mmfr2 : u64 ,
48
50
}
49
51
50
52
#[ cold]
51
53
fn _detect ( info : & mut CpuInfo ) {
52
- let AA64Reg { aa64isar0, aa64isar1, aa64mmfr2 } = imp:: aa64reg ( ) ;
54
+ let AA64Reg {
55
+ aa64isar0,
56
+ aa64isar1,
57
+ #[ cfg( test) ]
58
+ aa64isar3,
59
+ aa64mmfr2,
60
+ } = imp:: aa64reg ( ) ;
53
61
54
62
// ID_AA64ISAR0_EL1, AArch64 Instruction Set Attribute Register 0
55
63
// https://developer.arm.com/documentation/ddi0601/2024-12/AArch64-Registers/ID-AA64ISAR0-EL1--AArch64-Instruction-Set-Attribute-Register-0
@@ -65,6 +73,12 @@ fn _detect(info: &mut CpuInfo) {
65
73
if extract ( aa64isar1, 23 , 20 ) >= 0b0011 {
66
74
info. set ( CpuInfo :: HAS_RCPC3 ) ;
67
75
}
76
+ #[ cfg( test) ]
77
+ // ID_AA64ISAR3_EL1, AArch64 Instruction Set Attribute Register 3
78
+ // https://developer.arm.com/documentation/ddi0601/2024-12/AArch64-Registers/ID-AA64ISAR3-EL1--AArch64-Instruction-Set-Attribute-Register-3
79
+ if extract ( aa64isar3, 19 , 16 ) >= 0b0001 {
80
+ info. set ( CpuInfo :: HAS_LSFE ) ;
81
+ }
68
82
// ID_AA64MMFR2_EL1, AArch64 Memory Model Feature Register 2
69
83
// https://developer.arm.com/documentation/ddi0601/2024-12/AArch64-Registers/ID-AA64MMFR2-EL1--AArch64-Memory-Model-Feature-Register-2
70
84
if extract ( aa64mmfr2, 35 , 32 ) >= 0b0001 {
@@ -102,13 +116,27 @@ mod imp {
102
116
out( reg) aa64isar1,
103
117
options( pure, nomem, nostack, preserves_flags) ,
104
118
) ;
119
+ #[ cfg( test) ]
120
+ let aa64isar3: u64 ;
121
+ #[ cfg( test) ]
122
+ asm ! (
123
+ "mrs {0}, ID_AA64ISAR3_EL1" ,
124
+ out( reg) aa64isar3,
125
+ options( pure, nomem, nostack, preserves_flags) ,
126
+ ) ;
105
127
let aa64mmfr2: u64 ;
106
128
asm ! (
107
129
"mrs {0}, ID_AA64MMFR2_EL1" ,
108
130
out( reg) aa64mmfr2,
109
131
options( pure, nomem, nostack, preserves_flags) ,
110
132
) ;
111
- AA64Reg { aa64isar0, aa64isar1, aa64mmfr2 }
133
+ AA64Reg {
134
+ aa64isar0,
135
+ aa64isar1,
136
+ #[ cfg( test) ]
137
+ aa64isar3,
138
+ aa64mmfr2,
139
+ }
112
140
}
113
141
}
114
142
}
@@ -200,6 +228,8 @@ mod imp {
200
228
Some ( AA64Reg {
201
229
aa64isar0 : buf. ac_aa64isar0 ,
202
230
aa64isar1 : buf. ac_aa64isar1 ,
231
+ #[ cfg( test) ]
232
+ aa64isar3 : 0 ,
203
233
aa64mmfr2 : buf. ac_aa64mmfr2 ,
204
234
} )
205
235
}
@@ -213,7 +243,13 @@ mod imp {
213
243
// https://github.com/golang/sys/commit/ef9fd89ba245e184bdd308f7f2b4f3c551fa5b0f
214
244
match sysctl_cpu_id ( c ! ( "machdep.cpu0.cpu_id" ) ) {
215
245
Some ( cpu_id) => cpu_id,
216
- None => AA64Reg { aa64isar0 : 0 , aa64isar1 : 0 , aa64mmfr2 : 0 } ,
246
+ None => AA64Reg {
247
+ aa64isar0 : 0 ,
248
+ aa64isar1 : 0 ,
249
+ #[ cfg( test) ]
250
+ aa64isar3 : 0 ,
251
+ aa64mmfr2 : 0 ,
252
+ } ,
217
253
}
218
254
}
219
255
}
@@ -273,7 +309,13 @@ mod imp {
273
309
let aa64isar0 = sysctl64 ( & [ ffi:: CTL_MACHDEP , ffi:: CPU_ID_AA64ISAR0 ] ) . unwrap_or ( 0 ) ;
274
310
let aa64isar1 = sysctl64 ( & [ ffi:: CTL_MACHDEP , ffi:: CPU_ID_AA64ISAR1 ] ) . unwrap_or ( 0 ) ;
275
311
let aa64mmfr2 = sysctl64 ( & [ ffi:: CTL_MACHDEP , ffi:: CPU_ID_AA64MMFR2 ] ) . unwrap_or ( 0 ) ;
276
- AA64Reg { aa64isar0, aa64isar1, aa64mmfr2 }
312
+ AA64Reg {
313
+ aa64isar0,
314
+ aa64isar1,
315
+ #[ cfg( test) ]
316
+ aa64isar3 : 0 ,
317
+ aa64mmfr2,
318
+ }
277
319
}
278
320
279
321
fn sysctl64 ( mib : & [ ffi:: c_int ] ) -> Option < u64 > {
@@ -322,9 +364,10 @@ mod tests {
322
364
323
365
#[ test]
324
366
fn test_aa64reg ( ) {
325
- let AA64Reg { aa64isar0, aa64isar1, aa64mmfr2 } = imp:: aa64reg ( ) ;
367
+ let AA64Reg { aa64isar0, aa64isar1, aa64isar3 , aa64mmfr2 } = imp:: aa64reg ( ) ;
326
368
std:: eprintln!( "aa64isar0={}" , aa64isar0) ;
327
369
std:: eprintln!( "aa64isar1={}" , aa64isar1) ;
370
+ std:: eprintln!( "aa64isar3={}" , aa64isar3) ;
328
371
std:: eprintln!( "aa64mmfr2={}" , aa64mmfr2) ;
329
372
if cfg ! ( target_os = "openbsd" ) {
330
373
let output = Command :: new ( "sysctl" ) . arg ( "machdep" ) . output ( ) . unwrap ( ) ;
@@ -361,6 +404,12 @@ mod tests {
361
404
} else {
362
405
assert ! ( lrcpc < 0b0011 , "{}" , lrcpc) ;
363
406
}
407
+ let lsfe = extract ( aa64isar3, 19 , 16 ) ;
408
+ if detect ( ) . test ( CpuInfo :: HAS_LSFE ) {
409
+ assert_eq ! ( lsfe, 0b0001 ) ;
410
+ } else {
411
+ assert_eq ! ( lsfe, 0b0000 ) ;
412
+ }
364
413
let at = extract ( aa64mmfr2, 35 , 32 ) ;
365
414
if detect ( ) . test ( CpuInfo :: HAS_LSE2 ) {
366
415
assert_eq ! ( at, 0b0001 ) ;
@@ -496,6 +545,7 @@ mod tests {
496
545
Ok ( AA64Reg {
497
546
aa64isar0 : buf. ac_aa64isar0 ,
498
547
aa64isar1 : buf. ac_aa64isar1 ,
548
+ aa64isar3 : 0 ,
499
549
aa64mmfr2 : buf. ac_aa64mmfr2 ,
500
550
} )
501
551
}
0 commit comments