-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
build.rs
85 lines (70 loc) · 2.48 KB
/
build.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#[cfg(target_arch = "x86")]
use std::arch::x86::__cpuid;
use rustc_version::Channel;
#[cfg(target_arch = "x86_64")]
use std::arch::x86_64::__cpuid;
/// Performance of PDEP/PEXT relative to arithmetic/bit operations
#[derive(PartialOrd, PartialEq)]
enum PdepPerf {
VeryFast = 20,
Fast = 10,
Slow = 0,
}
#[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
fn pdep_speed() -> PdepPerf {
let leaf0 = unsafe { __cpuid(0) };
let mut buf = Vec::with_capacity(12);
buf.extend_from_slice(&leaf0.ebx.to_le_bytes());
buf.extend_from_slice(&leaf0.edx.to_le_bytes());
buf.extend_from_slice(&leaf0.ecx.to_le_bytes());
println!(
"Detected CPU manufacturer {}",
String::from_utf8_lossy(&buf)
);
if buf.as_slice() == b"AuthenticAMD" || buf.as_slice() == b"HygonGenuine" {
let leaf1 = unsafe { __cpuid(1) };
let family = (leaf1.eax >> 8) & 0b1111;
println!("family {}", family);
let extended_family = (leaf1.eax >> 20) & 0b11111111;
println!("extended_family {}", extended_family);
// Zen, Zen+, and Zen 2 CPUs have very poor PDEP/PEXT performance
if family == 0xF && (extended_family == 0x8 || extended_family == 0x9) {
println!("Detected Zen CPU");
return PdepPerf::Slow;
}
if family == 0xF && extended_family == 0xA {
println!("Detected Zen 3 CPU");
return PdepPerf::Fast;
}
}
PdepPerf::VeryFast
}
#[cfg(not(any(target_arch = "x86_64", target_arch = "x86")))]
fn pdep_speed() -> PdepPerf {
PdepPerf::Slow
}
fn main() {
println!("cargo:rustc-check-cfg=cfg(fast_pdep)");
println!("cargo:rustc-check-cfg=cfg(very_fast_pdep)");
println!("cargo:rustc-check-cfg=cfg(rustc_nightly)");
if std::env::var(
"CARGO_FEATURE_DANGEROUSLY_FORCE_ENABLE_PDEP_SINCE_I_REALLY_KNOW_WHAT_IM_DOING",
)
.is_ok()
{
println!("cargo:rustc-cfg=fast_pdep");
println!("cargo:rustc-cfg=very_fast_pdep");
} else if std::env::var("CARGO_FEATURE_NATIVE_OPTIMIZATIONS").is_ok() {
println!("Compiling with native optimizations");
let speed = pdep_speed();
if speed >= PdepPerf::Fast {
println!("cargo:rustc-cfg=fast_pdep");
}
if speed >= PdepPerf::VeryFast {
println!("cargo:rustc-cfg=very_fast_pdep");
}
}
if rustc_version::version_meta().unwrap().channel == Channel::Nightly {
println!("cargo:rustc-cfg=rustc_nightly");
}
}