Skip to content

Commit dd1b530

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

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

src/x86/runtime.rs

Lines changed: 33 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,42 @@ fn detect_features() -> usize {
257254
}
258255
}
259256

257+
if test_bit(proc_info_ecx, 21) {
258+
if is_amd() {
259+
value = set_bit(value, __Feature::tbm as u32);
260+
}
261+
}
262+
260263
value
261264
}
262265

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

0 commit comments

Comments
 (0)