Skip to content

Commit 1c257cc

Browse files
committed
[runtime] fix tbm detection
1 parent b40cbdf commit 1c257cc

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

src/x86/runtime.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ 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) {
213+
if test_bit(proc_info_ecx, 21) && is_amd() {
214214
value = set_bit(value, __Feature::tbm as u32);
215215
}
216216
if test_bit(proc_info_ecx, 23) {
@@ -260,6 +260,33 @@ fn detect_features() -> usize {
260260
value
261261
}
262262

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

0 commit comments

Comments
 (0)