OLD | NEW |
1 1,168c1,187 | 1 --- a\CpuArch.c»2015-03-25 08:17:41.042711000 -0400 |
2 < /* CpuArch.c -- CPU specific code | 2 +++ lzma_sdk\CpuArch.c» 2016-02-12 16:32:45.484718900 -0500 |
3 < 2010-10-26: Igor Pavlov : Public domain */ | 3 @@ -45,7 +45,8 @@ |
4 < | 4 "push %%EDX\n\t" |
5 < #include "CpuArch.h" | 5 "popf\n\t" |
6 < | 6 "andl %%EAX, %0\n\t": |
7 < #ifdef MY_CPU_X86_OR_AMD64 | 7 - "=c" (flag) : "c" (flag)); |
8 < | 8 + "=c" (flag) : "c" (flag): |
9 < #if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__) | 9 + "%eax", "%edx" ); |
10 < #define USE_ASM | 10 #endif |
11 < #endif | 11 return flag; |
12 < | 12 } |
13 < #if defined(USE_ASM) && !defined(MY_CPU_AMD64) | 13 @@ -79,7 +80,13 @@ |
14 < static UInt32 CheckFlag(UInt32 flag) | 14 #else |
15 < { | 15 |
16 < #ifdef _MSC_VER | 16 __asm__ __volatile__ ( |
17 < __asm pushfd; | 17 - #if defined(MY_CPU_X86) && defined(__PIC__) |
18 < __asm pop EAX; | 18 + #if defined(MY_CPU_AMD64) |
19 < __asm mov EDX, EAX; | 19 + "mov %%rbx, %%rdi\n" |
20 < __asm xor EAX, flag; | 20 + "cpuid\n" |
21 < __asm push EAX; | 21 + "xchg %%rdi, %%rbx\n" |
22 < __asm popfd; | 22 + : "=a" (*a) , |
23 < __asm pushfd; | 23 + "=D" (*b) , |
24 < __asm pop EAX; | 24 + #elif defined(MY_CPU_X86) && defined(__PIC__) |
25 < __asm xor EAX, EDX; | 25 "mov %%ebx, %%edi;" |
26 < __asm push EDX; | 26 "cpuid;" |
27 < __asm popfd; | 27 "xchgl %%ebx, %%edi;" |
28 < __asm and flag, EAX; | |
29 < #else | |
30 < __asm__ __volatile__ ( | |
31 < "pushf\n\t" | |
32 < "pop %%EAX\n\t" | |
33 < "movl %%EAX,%%EDX\n\t" | |
34 < "xorl %0,%%EAX\n\t" | |
35 < "push %%EAX\n\t" | |
36 < "popf\n\t" | |
37 < "pushf\n\t" | |
38 < "pop %%EAX\n\t" | |
39 < "xorl %%EDX,%%EAX\n\t" | |
40 < "push %%EDX\n\t" | |
41 < "popf\n\t" | |
42 < "andl %%EAX, %0\n\t": | |
43 < "=c" (flag) : "c" (flag)); | |
44 < #endif | |
45 < return flag; | |
46 < } | |
47 < #define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 <<
21) == 0) return False; | |
48 < #else | |
49 < #define CHECK_CPUID_IS_SUPPORTED | |
50 < #endif | |
51 < | |
52 < static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *
d) | |
53 < { | |
54 < #ifdef USE_ASM | |
55 < | |
56 < #ifdef _MSC_VER | |
57 < | |
58 < UInt32 a2, b2, c2, d2; | |
59 < __asm xor EBX, EBX; | |
60 < __asm xor ECX, ECX; | |
61 < __asm xor EDX, EDX; | |
62 < __asm mov EAX, function; | |
63 < __asm cpuid; | |
64 < __asm mov a2, EAX; | |
65 < __asm mov b2, EBX; | |
66 < __asm mov c2, ECX; | |
67 < __asm mov d2, EDX; | |
68 < | |
69 < *a = a2; | |
70 < *b = b2; | |
71 < *c = c2; | |
72 < *d = d2; | |
73 < | |
74 < #else | |
75 < | |
76 < __asm__ __volatile__ ( | |
77 < "cpuid" | |
78 < : "=a" (*a) , | |
79 < "=b" (*b) , | |
80 < "=c" (*c) , | |
81 < "=d" (*d) | |
82 < : "0" (function)) ; | |
83 < | |
84 < #endif | |
85 < | |
86 < #else | |
87 < | |
88 < int CPUInfo[4]; | |
89 < __cpuid(CPUInfo, function); | |
90 < *a = CPUInfo[0]; | |
91 < *b = CPUInfo[1]; | |
92 < *c = CPUInfo[2]; | |
93 < *d = CPUInfo[3]; | |
94 < | |
95 < #endif | |
96 < } | |
97 < | |
98 < Bool x86cpuid_CheckAndRead(Cx86cpuid *p) | |
99 < { | |
100 < CHECK_CPUID_IS_SUPPORTED | |
101 < MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]); | |
102 < MyCPUID(1, &p->ver, &p->b, &p->c, &p->d); | |
103 < return True; | |
104 < } | |
105 < | |
106 < static UInt32 kVendors[][3] = | |
107 < { | |
108 < { 0x756E6547, 0x49656E69, 0x6C65746E}, | |
109 < { 0x68747541, 0x69746E65, 0x444D4163}, | |
110 < { 0x746E6543, 0x48727561, 0x736C7561} | |
111 < }; | |
112 < | |
113 < int x86cpuid_GetFirm(const Cx86cpuid *p) | |
114 < { | |
115 < unsigned i; | |
116 < for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) | |
117 < { | |
118 < const UInt32 *v = kVendors[i]; | |
119 < if (v[0] == p->vendor[0] && | |
120 < v[1] == p->vendor[1] && | |
121 < v[2] == p->vendor[2]) | |
122 < return (int)i; | |
123 < } | |
124 < return -1; | |
125 < } | |
126 < | |
127 < Bool CPU_Is_InOrder() | |
128 < { | |
129 < Cx86cpuid p; | |
130 < int firm; | |
131 < UInt32 family, model; | |
132 < if (!x86cpuid_CheckAndRead(&p)) | |
133 < return True; | |
134 < family = x86cpuid_GetFamily(&p); | |
135 < model = x86cpuid_GetModel(&p); | |
136 < firm = x86cpuid_GetFirm(&p); | |
137 < switch (firm) | |
138 < { | |
139 < case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C
)); | |
140 < case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || mod
el == 0xA))); | |
141 < case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); | |
142 < } | |
143 < return True; | |
144 < } | |
145 < | |
146 < #if !defined(MY_CPU_AMD64) && defined(_WIN32) | |
147 < static Bool CPU_Sys_Is_SSE_Supported() | |
148 < { | |
149 < OSVERSIONINFO vi; | |
150 < vi.dwOSVersionInfoSize = sizeof(vi); | |
151 < if (!GetVersionEx(&vi)) | |
152 < return False; | |
153 < return (vi.dwMajorVersion >= 5); | |
154 < } | |
155 < #define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False; | |
156 < #else | |
157 < #define CHECK_SYS_SSE_SUPPORT | |
158 < #endif | |
159 < | |
160 < Bool CPU_Is_Aes_Supported() | |
161 < { | |
162 < Cx86cpuid p; | |
163 < CHECK_SYS_SSE_SUPPORT | |
164 < if (!x86cpuid_CheckAndRead(&p)) | |
165 < return False; | |
166 < return (p.c >> 25) & 1; | |
167 < } | |
168 < | |
169 < #endif | |
170 --- | |
171 > /* CpuArch.c -- CPU specific code | |
172 > 2010-10-26: Igor Pavlov : Public domain */ | |
173 > | |
174 > #include "CpuArch.h" | |
175 > | |
176 > #ifdef MY_CPU_X86_OR_AMD64 | |
177 > | |
178 > #if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__) | |
179 > #define USE_ASM | |
180 > #endif | |
181 > | |
182 > #if defined(USE_ASM) && !defined(MY_CPU_AMD64) | |
183 > static UInt32 CheckFlag(UInt32 flag) | |
184 > { | |
185 > #ifdef _MSC_VER | |
186 > __asm pushfd; | |
187 > __asm pop EAX; | |
188 > __asm mov EDX, EAX; | |
189 > __asm xor EAX, flag; | |
190 > __asm push EAX; | |
191 > __asm popfd; | |
192 > __asm pushfd; | |
193 > __asm pop EAX; | |
194 > __asm xor EAX, EDX; | |
195 > __asm push EDX; | |
196 > __asm popfd; | |
197 > __asm and flag, EAX; | |
198 > #else | |
199 > __asm__ __volatile__ ( | |
200 > "pushf\n\t" | |
201 > "pop %%EAX\n\t" | |
202 > "movl %%EAX,%%EDX\n\t" | |
203 > "xorl %0,%%EAX\n\t" | |
204 > "push %%EAX\n\t" | |
205 > "popf\n\t" | |
206 > "pushf\n\t" | |
207 > "pop %%EAX\n\t" | |
208 > "xorl %%EDX,%%EAX\n\t" | |
209 > "push %%EDX\n\t" | |
210 > "popf\n\t" | |
211 > "andl %%EAX, %0\n\t": | |
212 > "=c" (flag) : "c" (flag): | |
213 > "%eax", "%edx" ); | |
214 > #endif | |
215 > return flag; | |
216 > } | |
217 > #define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 <<
21) == 0) return False; | |
218 > #else | |
219 > #define CHECK_CPUID_IS_SUPPORTED | |
220 > #endif | |
221 > | |
222 > static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *
d) | |
223 > { | |
224 > #ifdef USE_ASM | |
225 > | |
226 > #ifdef _MSC_VER | |
227 > | |
228 > UInt32 a2, b2, c2, d2; | |
229 > __asm xor EBX, EBX; | |
230 > __asm xor ECX, ECX; | |
231 > __asm xor EDX, EDX; | |
232 > __asm mov EAX, function; | |
233 > __asm cpuid; | |
234 > __asm mov a2, EAX; | |
235 > __asm mov b2, EBX; | |
236 > __asm mov c2, ECX; | |
237 > __asm mov d2, EDX; | |
238 > | |
239 > *a = a2; | |
240 > *b = b2; | |
241 > *c = c2; | |
242 > *d = d2; | |
243 > | |
244 > #else | |
245 > | |
246 > #if defined(MY_CPU_AMD64) | |
247 > | |
248 > __asm__ __volatile__ ( | |
249 > "mov %%rbx, %%rdi\n" | |
250 > "cpuid\n" | |
251 > "xchg %%rdi, %%rbx\n" | |
252 > : "=a" (*a) , | |
253 > "=D" (*b) , | |
254 > "=c" (*c) , | |
255 > "=d" (*d) | |
256 > : "0" (function)) ; | |
257 > | |
258 > #else | |
259 > | |
260 > __asm__ __volatile__ ( | |
261 > "mov %%ebx, %%edi\n" | |
262 > "cpuid\n" | |
263 > "xchg %%edi, %%ebx\n" | |
264 > : "=a" (*a) , | |
265 > "=D" (*b) , | |
266 > "=c" (*c) , | |
267 > "=d" (*d) | |
268 > : "0" (function)) ; | |
269 > | |
270 > #endif | |
271 > | |
272 > #endif | |
273 > | |
274 > #else | |
275 > | |
276 > int CPUInfo[4]; | |
277 > __cpuid(CPUInfo, function); | |
278 > *a = CPUInfo[0]; | |
279 > *b = CPUInfo[1]; | |
280 > *c = CPUInfo[2]; | |
281 > *d = CPUInfo[3]; | |
282 > | |
283 > #endif | |
284 > } | |
285 > | |
286 > Bool x86cpuid_CheckAndRead(Cx86cpuid *p) | |
287 > { | |
288 > CHECK_CPUID_IS_SUPPORTED | |
289 > MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]); | |
290 > MyCPUID(1, &p->ver, &p->b, &p->c, &p->d); | |
291 > return True; | |
292 > } | |
293 > | |
294 > static UInt32 kVendors[][3] = | |
295 > { | |
296 > { 0x756E6547, 0x49656E69, 0x6C65746E}, | |
297 > { 0x68747541, 0x69746E65, 0x444D4163}, | |
298 > { 0x746E6543, 0x48727561, 0x736C7561} | |
299 > }; | |
300 > | |
301 > int x86cpuid_GetFirm(const Cx86cpuid *p) | |
302 > { | |
303 > unsigned i; | |
304 > for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++) | |
305 > { | |
306 > const UInt32 *v = kVendors[i]; | |
307 > if (v[0] == p->vendor[0] && | |
308 > v[1] == p->vendor[1] && | |
309 > v[2] == p->vendor[2]) | |
310 > return (int)i; | |
311 > } | |
312 > return -1; | |
313 > } | |
314 > | |
315 > Bool CPU_Is_InOrder() | |
316 > { | |
317 > Cx86cpuid p; | |
318 > int firm; | |
319 > UInt32 family, model; | |
320 > if (!x86cpuid_CheckAndRead(&p)) | |
321 > return True; | |
322 > family = x86cpuid_GetFamily(&p); | |
323 > model = x86cpuid_GetModel(&p); | |
324 > firm = x86cpuid_GetFirm(&p); | |
325 > switch (firm) | |
326 > { | |
327 > case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && model == 0x100C
)); | |
328 > case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || mod
el == 0xA))); | |
329 > case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF)); | |
330 > } | |
331 > return True; | |
332 > } | |
333 > | |
334 > #if !defined(MY_CPU_AMD64) && defined(_WIN32) | |
335 > static Bool CPU_Sys_Is_SSE_Supported() | |
336 > { | |
337 > OSVERSIONINFO vi; | |
338 > vi.dwOSVersionInfoSize = sizeof(vi); | |
339 > if (!GetVersionEx(&vi)) | |
340 > return False; | |
341 > return (vi.dwMajorVersion >= 5); | |
342 > } | |
343 > #define CHECK_SYS_SSE_SUPPORT if (!CPU_Sys_Is_SSE_Supported()) return False; | |
344 > #else | |
345 > #define CHECK_SYS_SSE_SUPPORT | |
346 > #endif | |
347 > | |
348 > Bool CPU_Is_Aes_Supported() | |
349 > { | |
350 > Cx86cpuid p; | |
351 > CHECK_SYS_SSE_SUPPORT | |
352 > if (!x86cpuid_CheckAndRead(&p)) | |
353 > return False; | |
354 > return (p.c >> 25) & 1; | |
355 > } | |
356 > | |
357 > #endif | |
OLD | NEW |