Home | History | Annotate | Download | only in lzma_sdk
      1 1,168c1,187
      2 < /* CpuArch.c -- CPU specific code
      3 < 2010-10-26: Igor Pavlov : Public domain */
      4 < 
      5 < #include "CpuArch.h"
      6 < 
      7 < #ifdef MY_CPU_X86_OR_AMD64
      8 < 
      9 < #if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
     10 < #define USE_ASM
     11 < #endif
     12 < 
     13 < #if defined(USE_ASM) && !defined(MY_CPU_AMD64)
     14 < static UInt32 CheckFlag(UInt32 flag)
     15 < {
     16 <   #ifdef _MSC_VER
     17 <   __asm pushfd;
     18 <   __asm pop EAX;
     19 <   __asm mov EDX, EAX;
     20 <   __asm xor EAX, flag;
     21 <   __asm push EAX;
     22 <   __asm popfd;
     23 <   __asm pushfd;
     24 <   __asm pop EAX;
     25 <   __asm xor EAX, EDX;
     26 <   __asm push EDX;
     27 <   __asm popfd;
     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 || model == 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 || model == 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
    358