| 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 |