Skip to content

Commit 90a83f2

Browse files
committed
[runtime] fix tbm detection
1 parent 7cb8c0c commit 90a83f2

File tree

1 file changed

+31
-3
lines changed

1 file changed

+31
-3
lines changed

src/x86/runtime.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,6 @@ fn detect_features() -> usize {
210210
if test_bit(proc_info_ecx, 20) {
211211
value = set_bit(value, __Feature::sse4_2 as u32);
212212
}
213-
if test_bit(proc_info_ecx, 21) {
214-
value = set_bit(value, __Feature::tbm as u32);
215-
}
216213
if test_bit(proc_info_ecx, 23) {
217214
value = set_bit(value, __Feature::popcnt as u32);
218215
}
@@ -257,9 +254,40 @@ fn detect_features() -> usize {
257254
}
258255
}
259256

257+
if test_bit(proc_info_ecx, 21) && is_amd() {
258+
value = set_bit(value, __Feature::tbm as u32);
259+
}
260+
260261
value
261262
}
262263

264+
/// Is this an AMD CPU?
265+
#[inline(never)]
266+
fn is_amd() -> bool {
267+
let ebx: u32;
268+
let edx: u32;
269+
let ecx: u32;
270+
// EAX = 0: Basic Information. The vendor ID is stored in 12 u8 ascii
271+
// chars, returned in EBX, EDX, and ECX (in that order):
272+
unsafe {
273+
asm!("cpuid"
274+
: "={ebx}"(ebx), "={ecx}"(ecx), "={edx}"(edx)
275+
: "{eax}"(0x0000_0000_u32), "{ecx}"(0 as u32)
276+
: : "volatile" );
277+
}
278+
let ebx: [u8; 4] = unsafe { ::std::mem::transmute(ebx) };
279+
let edx: [u8; 4] = unsafe { ::std::mem::transmute(edx) };
280+
let ecx: [u8; 4] = unsafe { ::std::mem::transmute(ecx) };
281+
#[cfg_attr(rustfmt, rustfmt_skip)]
282+
let vendor_id = [
283+
ebx[0], ebx[1], ebx[2], ebx[3],
284+
ecx[0], ecx[1], ecx[2], ecx[3],
285+
edx[0], edx[1], edx[2], edx[3],
286+
];
287+
let vendor_id_amd = b"AuthenticAMD";
288+
vendor_id == *vendor_id_amd
289+
}
290+
263291
/// This global variable is a bitset used to cache the features supported by
264292
/// the CPU.
265293
static FEATURES: AtomicUsize = AtomicUsize::new(::std::usize::MAX);

0 commit comments

Comments
 (0)