⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 archopt.c

📁 linux下的任天堂模拟器代码。供大家参考。
💻 C
字号:
/*Copyright (C) 2005-2007 Nach, grinvader ( http://www.zsnes.com )This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseversion 2 as published by the Free Software Foundation.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#ifdef _M_X64#define __x86_64__#endif#ifdef __GNUC__#ifdef __x86_64__#define cpuid(in, a, b, c, d) asm volatile("cpuid": "=a" (a), "=b" (b), "=c" (c), "=d" (d) : "a" (in));#else#define cpuid(in, a, b, c, d) asm volatile("\  pushl %%ebx;\  movl %%edi,%%ebx;\  cpuid;\  movl %%ebx,%%edi;\  popl %%ebx": "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (in));#endif#elsechar cpubuf[256];int z_in, z_a, z_b, z_c, z_d;void cpuid_run(){  _asm {    mov eax,z_in    cpuid    mov z_a,eax    mov z_b,ebx    mov z_c,ecx    mov z_d,edx  };}#define cpuid(in, a, b, c, d) z_in = in; cpuid_run(); a = z_a; b = z_b; c = z_c; d = z_d;#endifchar *x86_flags[] ={      "fpu",        "vme",        "de",         "pse",        "tsc",    "msr",      "pae",    "mce",       "cx8",       "apic",           0,         "sep",       "mtrr",    "pge",      "mca",   "cmov",       "pat",      "pse36",        "pn",     "clflush",            0,    "dts",     "acpi",    "mmx",      "fxsr",        "sse",      "sse2",          "ss",         "ht",     "tm",     "ia64",    "pbe",           0,            0,           0,             0,            0,        0,          0,        0,           0,            0,           0,     "syscall",            0,        0,          0,        0,           0,            0,           0,          "mp",         "nx",        0,   "mmxext",        0,           0,   "fxsr_opt",    "rdtscp",             0,            0,     "lm", "3dnowext",  "3dnow",  "recovery",    "longrun",           0,        "lrti",            0,        0,          0,        0,           0,            0,           0,             0,            0,        0,          0,        0,           0,            0,           0,             0,            0,        0,          0,        0,           0,            0,           0,             0,            0,        0,          0,        0,       "pni",            0,           0,     "monitor",     "ds_cpl",    "vmx",      "smx",    "est",       "tm2",      "ssse3",       "cid",             0,            0,   "cx16",     "xtpr",        0,           0,            0,       "dca",             0,            0,        0,          0,        0,           0,            0,           0,             0,            0,        0,          0,        0,           0,            0,       "rng",      "rng_en",            0,        0,      "ace", "ace_en",      "ace2",    "ace2_en",       "phe",      "phe_en",        "pmm", "pmm_en",          0,        0,           0,            0,           0,             0,            0,        0,          0,        0,           0,            0,           0,             0,            0,        0,          0,        0,   "lahf_lm", "cmp_legacy",       "svm",             0,  "cr8legacy",        0,          0,        0,           0,            0,           0,             0,            0,        0,          0,        0,           0,            0,           0,             0,            0,        0,          0,        0,           0,            0,           0,             0,            0,        0,          0,        0  };void add_flags(char *flags, unsigned int reg, unsigned int offset){  unsigned int i;  for (i = 0; i < 32; i++)  {    if ((reg & (1 << i)) && x86_flags[i+offset])    {      strcat(flags, x86_flags[i+offset]);      strcat(flags, " ");    }  }}int have_cpuid(){  int have = 0x200000;  #ifndef __x86_64__  #ifdef __GNUC__  asm volatile  (  "  pushfl;"  "  pop %%eax;"  "  movl %%eax,%%edx;"  "  xorl %%ecx,%%eax;"  "  push %%eax;"  "  popfl;"  "  pushfl;"  "  pop %%eax;"  "  xorl %%edx,%%eax;"    : "=a" (have)    : "c" (have)  );  #else  z_c = have;  _asm {    mov ecx,z_c    pushfd    pop eax    mov edx,eax    xor eax,ecx    push eax    popfd    pushfd    pop eax    xor eax,edx    mov z_a,eax  };  have = z_a;  #endif  #endif  return(have);}int main(int argc, const char *const *const argv){  char model_name[216];  char flags[216];  char cpu_family[216];  char vendor_id[216];  char model[216];  char *cpu = 0;  FILE *fp;  *model_name = 0;  *cpu_family = 0;  *vendor_id = 0;  *model = 0;  strcpy(flags, " ");  if ((fp = fopen("/proc/cpuinfo", "r")))  {    char line[256], key[40], arg[216];    const char *pattern = " %39[^:]: %215[ -~]"; // for sscanf    while (fgets(line, sizeof(line), fp) && sscanf(line, pattern, key, arg) == 2)    {      if (!strncmp(key, "model name", strlen("model name")) && !*model_name)      {        strcpy(model_name, arg);      }      else if (!strncmp(key, "flags", strlen("flags")) && !flags[1])      {        strcat(flags, arg);        strcat(flags, " ");      }      else if (!strncmp(key, "cpu family", strlen("cpu family")) && !*cpu_family)      {        strcpy(cpu_family, arg);      }      else if (!strncmp(key, "vendor_id", strlen("vendor_id")) && !*vendor_id)      {        strcpy(vendor_id, arg);      }      else if (!strncmp(key, "model", strlen("model")) && !*model)      {        strcpy(model, arg);      }    }    fclose(fp);  }  else if (have_cpuid())  {    unsigned int maxei, eax, ebx, ecx, edx, unused, i;    cpuid(0, unused, ebx, ecx, edx);    strncat(vendor_id, (char *)&ebx, 4);    strncat(vendor_id, (char *)&edx, 4);    strncat(vendor_id, (char *)&ecx, 4);    cpuid(1, eax, ebx, ecx, edx);    sprintf(model, "%u", (eax >> 4) & 0xf);    sprintf(cpu_family, "%u", (eax >> 8) & 0xf);    add_flags(flags, edx, 0);    add_flags(flags, ecx, 96);    cpuid(0x80000000, maxei, unused, unused, unused);    if (maxei >= 0x80000001)    {      cpuid(0x80000001, unused, unused, ecx, edx);      add_flags(flags, edx, 32);      add_flags(flags, ecx, 160);    }    //Transmeta    cpuid(0x80860000, eax, unused, unused, unused);    if (((eax & 0xffff0000) == 0x80860000) && (eax > 0x80860001))    {      cpuid(0x80860001, unused, unused, unused, edx);      add_flags(flags, edx, 64);    }    //Centaur    cpuid(0xC0000000, eax, unused, unused, unused);    if (eax >= 0xC0000001)    {      cpuid(0xC0000001, unused, unused, unused, edx);      add_flags(flags, edx, 128);    }    if (maxei >= 0x80000002)    {      for (i = 0x80000002; i <= 0x80000004; i++)      {        cpuid(i, eax, ebx, ecx, edx);        strncat(model_name, (char *)&eax, 4);        strncat(model_name, (char *)&ebx, 4);        strncat(model_name, (char *)&ecx, 4);        strncat(model_name, (char *)&edx, 4);      }    }  }  if (argc > 1)  {    printf("vendor_id: %s\n", vendor_id);    printf("cpu family: %s\n", cpu_family);    printf("model: %s\n", model);    printf("model name: %s\n", model_name);    printf("flags:%s\n", flags);  }#if __GNUC__ > 3#if __GNUC__ > 4 || __GNUC_MINOR__ > 1  cpu = "native";#endif#endif  if (!cpu)  {    if (!cpu && *cpu_family && *vendor_id)    {      #ifdef __GNUC__      if (!strcmp(vendor_id, "AuthenticAMD") || strstr(model_name, "AMD"))      {        if (strstr(flags, " mmx "))        {          #if __GNUC__ > 2          if (strstr(flags, " 3dnow "))          {            if (strstr(flags, " 3dnowext ") && (atoi(cpu_family) > 5))            {              #if __GNUC__ > 3 || __GNUC_MINOR__ > 0              if (strstr(flags, " sse "))              {                #if __GNUC__ > 3 || __GNUC_MINOR__ > 3                if (strstr(flags, " sse2 ") && strstr(flags, " lm ")) //Need two checks to protect Semprons                {                  if (strstr(model_name, "Opteron"))                  {                    cpu = "opteron";                  }                  else if (strstr(model_name, "Athlon(tm) 64")) //Also athlon-fx                  {                    cpu = "athlon64";                  }                  else                  {                    cpu = "k8";                  }                }                #endif                if (!cpu)                {                  if (strstr(model_name, "Athlon(tm) 4"))                  {                    cpu = "athlon-4";                  }                  else if (strstr(model_name, "Athlon(tm) MP"))                  {                    cpu = "athlon-mp";                  }                  else                  {                    cpu = "athlon-xp";                  }                }              }              if (!cpu && (atoi(model) > 3))              {                cpu = "athlon-tbird";              }              #endif              if (!cpu)              {                cpu = "athlon";              }            }            #if __GNUC__ > 3 || __GNUC_MINOR__ > 0            if (!cpu)            {              int model_num = atoi(model);              if ((model_num == 9) || (model_num >= 13))              {                cpu = "k6-3";              }              else              {                cpu = "k6-2";              }            }            #endif          }          #endif          if (!cpu)          {            cpu = "k6";          }        }      }      else if (!strcmp(vendor_id, "GenuineIntel") || strstr(model_name, "Intel"))      {        #if __GNUC__ > 2        if (strstr(flags, " mmx "))        {          if (strstr(flags, " sse "))          {            if (strstr(flags, " sse2 "))            {              #if __GNUC__ > 3 || __GNUC_MINOR__ > 2              if (strstr(flags, " pni ") && strcmp(cpu_family, "6"))              {                if (strstr(flags, " lm "))                {                  cpu = "nocona";                }                else                {                  cpu = "prescott";                }              }              #endif              if (!cpu)              {                if (!strcmp(cpu_family, "6"))                {                  #if __GNUC__ > 3 || __GNUC_MINOR__ > 3                  cpu = "pentium-m";                  #else                  cpu = "pentium3";                  #endif                }                else                {                  #if __GNUC__ > 3 || __GNUC_MINOR__ > 3                  if (strstr(model_name, "Mobile"))                  {                    cpu = "pentium4m";                  }                  #endif                  if (!cpu)                  {                    cpu = "pentium4";                  }                }              }            }            else            {              #if __GNUC__ > 3 || __GNUC_MINOR__ > 3              if (strstr(model_name, "Mobile"))              {                cpu = "pentium3m";              }              #endif              if (!cpu)              {                cpu = "pentium3";              }            }          }          else          {            if (!strcmp(cpu_family, "6"))            {              cpu = "pentium2";            }            else            {              cpu = "pentium-mmx";            }          }        }        #endif        if (!cpu)        {          int family = atoi(cpu_family);          if (family > 5)          {            cpu = "pentiumpro";          }          else if (family == 5)          {            cpu = "pentium";          }        }      }      #if __GNUC__ > 2      #if __GNUC__ > 3 || __GNUC_MINOR__ > 2      else if (!strcmp(vendor_id, "CentaurHauls") && strstr(flags, " mmx "))      {        if (strstr(flags, " 3dnow "))        {          if (atoi(cpu_family) > 5)          {            cpu = "c3";          }          else          {            cpu = "winchip2";          }        }        #if __GNUC__ > 3 || __GNUC_MINOR__ > 3        else if (strstr(flags, " sse "))        {          cpu = "c3-2";        }        #endif        if (!cpu)        {          cpu = "winchip-c6";        }      }      #endif      #endif      if (!cpu)      {        int family = atoi(cpu_family);        if (family > 5)        {          cpu = "i686";        }        else if (family == 5)        {          cpu = "i586";        }        else if (family == 4)        {          cpu = "i486";        }        else        {          cpu = "i386";        }      }      #else //MSVC      cpu = cpubuf;      *cpu = 0;      if (strstr(flags, " sse2 "))      {        strcat(cpu, " /arch:SSE2");      }      else if (strstr(flags, " sse "))      {        strcat(cpu, " /arch:SSE");      }      #ifdef __x86_64__      if (strstr(flags, " lm ")) //64 bit      {        if (!strcmp(vendor_id, "AuthenticAMD") || strstr(model_name, "AMD"))        {          strcat(cpu, " /favor:AMD64");        }        else if (!strcmp(vendor_id, "GenuineIntel") || strstr(model_name, "Intel"))        {          strcat(cpu, " /favor:EM64T");        }      }      #endif      #endif    }    else    {      puts("Could not open /proc/cpuinfo, and CPUID instruction not available.");      return(1);    }  }  puts(cpu);  return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -