-
Notifications
You must be signed in to change notification settings - Fork 22
/
ir_cpuinfo.c
61 lines (53 loc) · 1.42 KB
/
ir_cpuinfo.c
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
/*
* IR - Lightweight JIT Compilation Framework
* (CPU framework for x86)
* Copyright (C) 2023 by IR project.
* Authors: Anatol Belski <[email protected]>
*/
#include "ir.h"
#if defined(IR_TARGET_X86) || defined(IR_TARGET_X64)
#ifndef _WIN32
IR_ALWAYS_INLINE void ir_cpuid_ex(uint32_t info[4], uint32_t function, uint32_t index)
{
asm volatile("cpuid"
: "=a" (info[0]),
"=b" (info[1]),
"=c" (info[2]),
"=d" (info[3])
: "0" (function), "2" (index)
: "memory");
}
IR_ALWAYS_INLINE void ir_cpuid(uint32_t info[4], uint32_t function)
{
ir_cpuid_ex(info, function, 0);
}
#else
#define ir_cpuid_ex __cpuidex
#define ir_cpuid __cpuid
#endif
/* Intel SDM Vol. 2A */
uint32_t ir_cpuinfo(void)
{
uint32_t ret = 0;
uint32_t info_0x1[4] = {0}, info_0x7_0[4] = {0};
#define bit(mask, pos) (((mask) >> (pos)) & 1U)
ir_cpuid(info_0x1, 0x1);
if (bit(info_0x1[3], 26U)) ret |= IR_X86_SSE2;
if (bit(info_0x1[2], 0U)) ret |= IR_X86_SSE3;
if (bit(info_0x1[2], 9U)) ret |= IR_X86_SSSE3;
if (bit(info_0x1[2], 19U)) ret |= IR_X86_SSE41;
if (bit(info_0x1[2], 20U)) ret |= IR_X86_SSE42;
if (bit(info_0x1[2], 28U)) ret |= IR_X86_AVX;
ir_cpuid_ex(info_0x7_0, 0x7, 0);
if (bit(info_0x7_0[1], 5U)) ret |= IR_X86_AVX2;
if (bit(info_0x7_0[1], 3U)) ret |= IR_X86_BMI1;
if (bit(info_0x7_0[2], 25U)) ret |= IR_X86_CLDEMOTE;
#undef bit
return ret;
}
#else
uint32_t ir_cpuinfo(void)
{
return 0;
}
#endif /* IR_TARGET_X86 || IR_TARGET_X64 */