Submitted By: Robert Connolly (ashes) Date: 2005-11-13 Initial Package Version: 5.93 Upstream Status: pending Origin: Scot McPherson and Zack Winkles Description: Fix the output of uname once and for all. This is the position independent version. $ uname -m # This always worked. i686 $ uname -i # Used to report 'unknown'. i386 $ uname -p # Likewise. athlon-4 Now 'uname -p' can be used by GCC's mtune/mcpu and march options. For example: CFLAGS="-march=$(uname -m) -mtune=$(uname -p)" diff -Naur coreutils-5.93.orig/src/uname.c coreutils-5.93/src/uname.c --- coreutils-5.93.orig/src/uname.c 2005-09-15 19:57:04.000000000 +0000 +++ coreutils-5.93/src/uname.c 2005-11-13 19:18:35.000000000 +0000 @@ -29,6 +29,26 @@ # include #endif +#ifdef linux +/* Thanks to the ffmpeg team for this PIC version of cpuid() */ +#ifdef ARCH_X86_64 +# define REG_b "rbx" +# define REG_S "rsi" +#else +# define REG_b "ebx" +# define REG_S "esi" +#endif +#define cpuid(index,eax,ebx,ecx,edx)\ + __asm __volatile\ + ("mov %%"REG_b", %%"REG_S"\n\t"\ + "cpuid\n\t"\ + "xchg %%"REG_b", %%"REG_S\ + : "=a" (eax), "=S" (ebx),\ + "=c" (ecx), "=d" (edx)\ + : "0" (index)); +int has_sse( void ); +#endif + #if HAVE_SYS_SYSCTL_H # if HAVE_SYS_PARAM_H # include /* needed for OpenBSD 3.0 */ @@ -256,6 +276,99 @@ if (0 <= sysinfo (SI_ARCHITECTURE, processor, sizeof processor)) element = processor; } +#else + { + struct utsname u; + uname (&u); + element = u.machine; +#ifdef linux +/****************************************************************************** + * + * Hello, major hack. I shouldn't have to do this. struct utsname should + * have another element with this info in it. There's probably a struct + * somewhere that has this info, I just don't know where it is. + * + *****************************************************************************/ + + if( !strcmp( element, "i586" ) || !strcmp( element, "i686" ) ) { + int eax, ebx, ecx, edx, unused; + int model, family, sse; + + cpuid(0,unused,ebx,ecx,edx); + cpuid(1,eax,unused,unused,unused); + model = (eax >> 4) & 0xf; + family = (eax >> 8) & 0xf; + + switch(ebx) { + case 0x756e6547: // Intel + switch( family ) { + case 5: // Pentium + if( model <= 3 ) + element="pentium"; + if( model > 3 ) + element="pentium-mmx"; + break; + case 6: // PentiumPro - Pentium III + if( model == 1 ) // Pentium Pro + element="pentiumpro"; + if( ( model == 3 ) || ( model == 5 ) || + ( model == 6 ) ) // Pentium II + element="pentium2"; + if( ( model == 7 ) || ( model == 8 ) || + ( model == 10 ) || ( model == 11 ) ) // These are all Pentium III + element="pentium3"; + break; + case 15: // Pentium4 + if( model == 3 ) // Prescott + element="prescott"; + else + element="pentium4"; + break; + default: + break; + } // end switch( family ) + break; + case 0x68747541: // AMD + switch(family) { + case 5: + if( ( model == 0 ) || ( model == 1 ) || + ( model == 2 ) || ( model == 3 ) ) // K5 + element="i586"; + if( ( model == 6 ) || ( model == 7 ) ) // K6 + element="k6"; + if( model == 8 ) // K6-2 + element="k6-2"; + if( model == 9 ) // K6-3 + element="k6-3"; + break; + case 6: + if( model <= 4 ) + element="athlon"; + if( model > 4 ) { + sse = has_sse(); + if( sse == 0 ) + element="athlon"; + if( sse == 1 ) + element="athlon-4"; + } + break; + case 15: + element="athlon-4"; + break; + default: + break; + } // end switch( family ) + break; + case 0x69727943: // Cyrix + element="i386"; // who knows what cyrix supports, lets be safe + break; + default: + break; + } // end switch(ebx) + } + +#endif + } #endif #ifdef UNAME_PROCESSOR if (element == unknown) @@ -293,7 +406,7 @@ if (toprint & PRINT_HARDWARE_PLATFORM) { - char const *element = unknown; + char *element = unknown; #if HAVE_SYSINFO && defined SI_PLATFORM { static char hardware_platform[257]; @@ -301,6 +414,15 @@ hardware_platform, sizeof hardware_platform)) element = hardware_platform; } +#else + { + struct utsname u; + uname (&u); + element = u.machine; + if (strlen (element) == 4 && element[0] == 'i' && element[2] == '8' + && element[3] == '6') + element[1] = '3'; + } #endif #ifdef UNAME_HARDWARE_PLATFORM if (element == unknown) @@ -323,3 +445,29 @@ exit (EXIT_SUCCESS); } + +#ifdef linux + +/****************************************************************************** + * + * int has_sse( void ) + * Checks Athlon CPU's to see if they support SSE. + * + *****************************************************************************/ + +int has_sse( void ) +{ + unsigned long edx, unused; + int sse; + cpuid(1,unused,unused,unused,edx); + // I think, I need this tested on a Duron with SSE + // and one without it. + sse = edx & 0x2000000; + if( sse == 0 ) { + return 0; + } else { + return 1; + } + +} +#endif