Skip to main content

luaur_code_gen/functions/
get_cpu_features_x_64.rs

1pub fn get_cpu_features_x_64() -> u32 {
2    let mut result: u32 = 0;
3
4    let mut cpuinfo: [i32; 4] = [0, 0, 0, 0];
5
6    if crate::macros::codegen_target_x_64::CODEGEN_TARGET_X64 {
7        #[cfg(any(target_arch = "x86_64", target_arch = "x86"))]
8        {
9            // Use the `core::arch` CPUID intrinsic rather than hand-rolled inline
10            // asm: the `cpuid` instruction clobbers `rbx`/`ebx`, which LLVM
11            // reserves and forbids as an `asm!` operand ("rbx is used internally
12            // by LLVM"). `__cpuid` saves/restores it for us and returns a
13            // `CpuidResult { eax, ebx, ecx, edx }`. Works on every x86 OS.
14            #[cfg(target_arch = "x86_64")]
15            {
16                unsafe {
17                    let r = core::arch::x86_64::__cpuid(1);
18                    cpuinfo = [r.eax as i32, r.ebx as i32, r.ecx as i32, r.edx as i32];
19                }
20            }
21
22            #[cfg(target_arch = "x86")]
23            {
24                unsafe {
25                    let r = core::arch::x86::__cpuid(1);
26                    cpuinfo = [r.eax as i32, r.ebx as i32, r.ecx as i32, r.edx as i32];
27                }
28            }
29        }
30    }
31
32    let feature_fma3 = crate::enums::features_x_64::FeaturesX64::Feature_FMA3 as u32;
33    let feature_avx = crate::enums::features_x_64::FeaturesX64::Feature_AVX as u32;
34
35    if (cpuinfo[2] & 0x00001000) != 0 {
36        result |= feature_fma3;
37    }
38
39    if (cpuinfo[2] & 0x10000000) != 0 {
40        result |= feature_avx;
41    }
42
43    result
44}