--- tools/archopt.c.old 2006-12-29 06:50:31.000000000 +0100 +++ tools/archopt.c 2007-07-23 00:11:51.000000000 +0200 @@ -1,8 +1,30 @@ +/* +Copyright (C) 2005-2007 Nach, grinvader ( http://www.zsnes.com ) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +version 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 of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + #include #include #include #include +#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 @@ -13,6 +35,22 @@ movl %%ebx,%%edi;\ popl %%ebx": "=a" (a), "=D" (b), "=c" (c), "=d" (d) : "a" (in)); #endif +#else +char 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; +#endif char *x86_flags[] = { "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", @@ -62,6 +100,7 @@ { int have = 0x200000; #ifndef __x86_64__ + #ifdef __GNUC__ asm volatile ( " pushfl;" @@ -76,6 +115,23 @@ : "=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); } @@ -196,238 +252,268 @@ cpu = "native"; #endif #endif - - if (!cpu && *cpu_family && *vendor_id) + if (!cpu) { - if (!strcmp(vendor_id, "AuthenticAMD") || strstr(model_name, "AMD")) + if (!cpu && *cpu_family && *vendor_id) { - if (strstr(flags, " mmx ")) + #ifdef __GNUC__ + if (!strcmp(vendor_id, "AuthenticAMD") || strstr(model_name, "AMD")) { - #if __GNUC__ > 2 - if (strstr(flags, " 3dnow ")) + if (strstr(flags, " mmx ")) { - if (strstr(flags, " 3dnowext ") && (atoi(cpu_family) > 5)) + #if __GNUC__ > 2 + if (strstr(flags, " 3dnow ")) { - #if __GNUC__ > 3 || __GNUC_MINOR__ > 0 - if (strstr(flags, " sse ")) + if (strstr(flags, " 3dnowext ") && (atoi(cpu_family) > 5)) { - #if __GNUC__ > 3 || __GNUC_MINOR__ > 3 - if (strstr(flags, " sse2 ") && strstr(flags, " lm ")) //Need two checks to protect Semprons + #if __GNUC__ > 3 || __GNUC_MINOR__ > 0 + if (strstr(flags, " sse ")) { - if (strstr(model_name, "Opteron")) - { - cpu = "opteron"; - } - else if (strstr(model_name, "Athlon(tm) 64")) //Also athlon-fx + #if __GNUC__ > 3 || __GNUC_MINOR__ > 3 + if (strstr(flags, " sse2 ") && strstr(flags, " lm ")) //Need two checks to protect Semprons { - cpu = "athlon64"; + if (strstr(model_name, "Opteron")) + { + cpu = "opteron"; + } + else if (strstr(model_name, "Athlon(tm) 64")) //Also athlon-fx + { + cpu = "athlon64"; + } + else + { + cpu = "k8"; + } } - else + #endif + if (!cpu) { - cpu = "k8"; + 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) { - 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"; - } + cpu = "athlon"; } } - if (!cpu && (atoi(model) > 3)) - { - cpu = "athlon-tbird"; - } - #endif - + #if __GNUC__ > 3 || __GNUC_MINOR__ > 0 if (!cpu) { - cpu = "athlon"; + int model_num = atoi(model); + if ((model_num == 9) || (model_num >= 13)) + { + cpu = "k6-3"; + } + else + { + cpu = "k6-2"; + } } + #endif } + #endif - #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"; - } + cpu = "k6"; } - #endif - } - #endif - - if (!cpu) - { - cpu = "k6"; } } - } - else if (!strcmp(vendor_id, "GenuineIntel") || strstr(model_name, "Intel")) - { - #if __GNUC__ > 2 - if (strstr(flags, " mmx ")) + else if (!strcmp(vendor_id, "GenuineIntel") || strstr(model_name, "Intel")) { - if (strstr(flags, " sse ")) + #if __GNUC__ > 2 + if (strstr(flags, " mmx ")) { - if (strstr(flags, " sse2 ")) + if (strstr(flags, " sse ")) { - #if __GNUC__ > 3 || __GNUC_MINOR__ > 2 - if (strstr(flags, " pni ") && strcmp(cpu_family, "6")) + if (strstr(flags, " sse2 ")) { - if (strstr(flags, " lm ")) + #if __GNUC__ > 3 || __GNUC_MINOR__ > 2 + if (strstr(flags, " pni ") && strcmp(cpu_family, "6")) { - cpu = "nocona"; + if (strstr(flags, " lm ")) + { + cpu = "nocona"; + } + else + { + cpu = "prescott"; + } } - else + #endif + + if (!cpu) { - cpu = "prescott"; + 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"; + } + } } } - #endif - - if (!cpu) + else { - if (!strcmp(cpu_family, "6")) + #if __GNUC__ > 3 || __GNUC_MINOR__ > 3 + if (strstr(model_name, "Mobile")) { - #if __GNUC__ > 3 || __GNUC_MINOR__ > 3 - cpu = "pentium-m"; - #else - cpu = "pentium3"; - #endif + cpu = "pentium3m"; } - else - { - #if __GNUC__ > 3 || __GNUC_MINOR__ > 3 - if (strstr(model_name, "Mobile")) - { - cpu = "pentium4m"; - } - #endif + #endif - if (!cpu) - { - cpu = "pentium4"; - } + if (!cpu) + { + cpu = "pentium3"; } } } else { - #if __GNUC__ > 3 || __GNUC_MINOR__ > 3 - if (strstr(model_name, "Mobile")) + if (!strcmp(cpu_family, "6")) { - cpu = "pentium3m"; + cpu = "pentium2"; } - #endif - - if (!cpu) + else { - cpu = "pentium3"; + cpu = "pentium-mmx"; } } } - else + #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 (!strcmp(cpu_family, "6")) + if (atoi(cpu_family) > 5) { - cpu = "pentium2"; + cpu = "c3"; } else { - cpu = "pentium-mmx"; + 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 = "pentiumpro"; + cpu = "i686"; } else if (family == 5) { - cpu = "pentium"; + cpu = "i586"; } - } - } - #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) + else if (family == 4) { - cpu = "c3"; + cpu = "i486"; } else { - cpu = "winchip2"; + cpu = "i386"; } } - #if __GNUC__ > 3 || __GNUC_MINOR__ > 3 + #else //MSVC + cpu = cpubuf; + *cpu = 0; + + if (strstr(flags, " sse2 ")) + { + strcat(cpu, " /arch:SSE2"); + } else if (strstr(flags, " sse ")) { - cpu = "c3-2"; + strcat(cpu, " /arch:SSE"); } - #endif - if (!cpu) + #ifdef __x86_64__ + if (strstr(flags, " lm ")) //64 bit { - cpu = "winchip-c6"; + 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 } - #endif - #endif - - if (!cpu) + else { - 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"; - } + puts("Could not open /proc/cpuinfo, and CPUID instruction not available."); + return(1); } - puts(cpu); - } - else - { - puts("Could not open /proc/cpuinfo, and CPUID instruction not available."); - return(1); } + puts(cpu); return(0); }