Don't udpate LastOverSpeedTick when using aqua_speed
[ryzomcore.git] / nel / 3rdparty / seven_zip / CpuArch.c
blob02e482e088a56ca5e4a71ed3949eb50a1c2f50b4
1 /* CpuArch.c -- CPU specific code
2 2018-02-18: Igor Pavlov : Public domain */
4 #include "Precomp.h"
6 #include "CpuArch.h"
8 #ifdef MY_CPU_X86_OR_AMD64
10 #if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
11 #define USE_ASM
12 #endif
14 #if !defined(USE_ASM) && _MSC_VER >= 1500
15 #include <intrin.h>
16 #endif
18 #if defined(USE_ASM) && !defined(MY_CPU_AMD64)
19 static UInt32 CheckFlag(UInt32 flag)
21 #ifdef _MSC_VER
22 __asm pushfd;
23 __asm pop EAX;
24 __asm mov EDX, EAX;
25 __asm xor EAX, flag;
26 __asm push EAX;
27 __asm popfd;
28 __asm pushfd;
29 __asm pop EAX;
30 __asm xor EAX, EDX;
31 __asm push EDX;
32 __asm popfd;
33 __asm and flag, EAX;
34 #else
35 __asm__ __volatile__ (
36 "pushf\n\t"
37 "pop %%EAX\n\t"
38 "movl %%EAX,%%EDX\n\t"
39 "xorl %0,%%EAX\n\t"
40 "push %%EAX\n\t"
41 "popf\n\t"
42 "pushf\n\t"
43 "pop %%EAX\n\t"
44 "xorl %%EDX,%%EAX\n\t"
45 "push %%EDX\n\t"
46 "popf\n\t"
47 "andl %%EAX, %0\n\t":
48 "=c" (flag) : "c" (flag) :
49 "%eax", "%edx");
50 #endif
51 return flag;
53 #define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
54 #else
55 #define CHECK_CPUID_IS_SUPPORTED
56 #endif
58 void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
60 #ifdef USE_ASM
62 #ifdef _MSC_VER
64 UInt32 a2, b2, c2, d2;
65 __asm xor EBX, EBX;
66 __asm xor ECX, ECX;
67 __asm xor EDX, EDX;
68 __asm mov EAX, function;
69 __asm cpuid;
70 __asm mov a2, EAX;
71 __asm mov b2, EBX;
72 __asm mov c2, ECX;
73 __asm mov d2, EDX;
75 *a = a2;
76 *b = b2;
77 *c = c2;
78 *d = d2;
80 #else
82 __asm__ __volatile__ (
83 #if defined(MY_CPU_AMD64) && defined(__PIC__)
84 "mov %%rbx, %%rdi;"
85 "cpuid;"
86 "xchg %%rbx, %%rdi;"
87 : "=a" (*a) ,
88 "=D" (*b) ,
89 #elif defined(MY_CPU_X86) && defined(__PIC__)
90 "mov %%ebx, %%edi;"
91 "cpuid;"
92 "xchgl %%ebx, %%edi;"
93 : "=a" (*a) ,
94 "=D" (*b) ,
95 #else
96 "cpuid"
97 : "=a" (*a) ,
98 "=b" (*b) ,
99 #endif
100 "=c" (*c) ,
101 "=d" (*d)
102 : "0" (function)) ;
104 #endif
106 #else
108 int CPUInfo[4];
109 __cpuid(CPUInfo, function);
110 *a = CPUInfo[0];
111 *b = CPUInfo[1];
112 *c = CPUInfo[2];
113 *d = CPUInfo[3];
115 #endif
118 BoolInt x86cpuid_CheckAndRead(Cx86cpuid *p)
120 CHECK_CPUID_IS_SUPPORTED
121 MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
122 MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
123 return True;
126 static const UInt32 kVendors[][3] =
128 { 0x756E6547, 0x49656E69, 0x6C65746E},
129 { 0x68747541, 0x69746E65, 0x444D4163},
130 { 0x746E6543, 0x48727561, 0x736C7561}
133 int x86cpuid_GetFirm(const Cx86cpuid *p)
135 unsigned i;
136 for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
138 const UInt32 *v = kVendors[i];
139 if (v[0] == p->vendor[0] &&
140 v[1] == p->vendor[1] &&
141 v[2] == p->vendor[2])
142 return (int)i;
144 return -1;
147 BoolInt CPU_Is_InOrder()
149 Cx86cpuid p;
150 int firm;
151 UInt32 family, model;
152 if (!x86cpuid_CheckAndRead(&p))
153 return True;
155 family = x86cpuid_GetFamily(p.ver);
156 model = x86cpuid_GetModel(p.ver);
158 firm = x86cpuid_GetFirm(&p);
160 switch (firm)
162 case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
163 /* In-Order Atom CPU */
164 model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
165 || model == 0x26 /* 45 nm, Z6xx */
166 || model == 0x27 /* 32 nm, Z2460 */
167 || model == 0x35 /* 32 nm, Z2760 */
168 || model == 0x36 /* 32 nm, N2xxx, D2xxx */
169 )));
170 case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
171 case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
173 return True;
176 #if !defined(MY_CPU_AMD64) && defined(_WIN32)
177 #include <windows.h>
178 static BoolInt CPU_Sys_Is_SSE_Supported()
180 OSVERSIONINFO vi;
181 vi.dwOSVersionInfoSize = sizeof(vi);
182 if (!GetVersionEx(&vi))
183 return False;
184 return (vi.dwMajorVersion >= 5);
186 #define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False;
187 #else
188 #define CHECK_SYS_SSE_SUPPORT
189 #endif
191 BoolInt CPU_Is_Aes_Supported()
193 Cx86cpuid p;
194 CHECK_SYS_SSE_SUPPORT
195 if (!x86cpuid_CheckAndRead(&p))
196 return False;
197 return (p.c >> 25) & 1;
200 BoolInt CPU_IsSupported_PageGB()
202 Cx86cpuid cpuid;
203 if (!x86cpuid_CheckAndRead(&cpuid))
204 return False;
206 UInt32 d[4] = { 0 };
207 MyCPUID(0x80000000, &d[0], &d[1], &d[2], &d[3]);
208 if (d[0] < 0x80000001)
209 return False;
212 UInt32 d[4] = { 0 };
213 MyCPUID(0x80000001, &d[0], &d[1], &d[2], &d[3]);
214 return (d[3] >> 26) & 1;
218 #endif