diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-17 00:32:19 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-17 00:32:19 +0000 |
commit | 0d382a262c0638d0f572fc37193ccc5ed3dc895f (patch) | |
tree | 8578dcddfce4191f3f7a142a37769df7add48475 /k9vamps/cputest.cpp | |
download | k9copy-0d382a262c0638d0f572fc37193ccc5ed3dc895f.tar.gz k9copy-0d382a262c0638d0f572fc37193ccc5ed3dc895f.zip |
Added old abandoned version of k9copy
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/k9copy@1091546 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'k9vamps/cputest.cpp')
-rw-r--r-- | k9vamps/cputest.cpp | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/k9vamps/cputest.cpp b/k9vamps/cputest.cpp new file mode 100644 index 0000000..643742b --- /dev/null +++ b/k9vamps/cputest.cpp @@ -0,0 +1,274 @@ +/* Cpu detection code, extracted from mmx.h ((c)1997-99 by H. Dietz + and R. Fisher). Converted to C and improved by Fabrice Bellard */ + +#include <stdio.h> +#include <stdlib.h> +#include "ac.h" + +#ifdef HAVE_STRING_H +# include <string.h> +#endif + +#ifdef ARCH_X86_64 +# define REG_b "rbx" +# define REG_S "rsi" +#else +# define REG_b "ebx" +# define REG_S "esi" +#endif + +//exported + int mm_flag; + +/* ebx saving is necessary for PIC. gcc seems unable to see it alone */ +#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)); + +#define CPUID_STD_MMX 0x00800000 +#define CPUID_STD_SSE 0x02000000 +#define CPUID_STD_SSE2 0x04000000 +#define CPUID_STD_SSE3 0x00000001 // ECX! +#define CPUID_EXT_AMD_3DNOW 0x80000000 +#define CPUID_EXT_AMD_3DNOWEXT 0x40000000 +#define CPUID_EXT_AMD_MMXEXT 0x00400000 +#define CPUID_EXT_CYR_MMX 0x00800000 +#define CPUID_EXT_CYR_MMXEXT 0x01000000 + +/* Function to test if multimedia instructions are supported... */ +static int mm_support(void) +{ + int rval = 0; +#if defined(ARCH_X86) || defined(ARCH_X86_64) + int eax, ebx, ecx, edx; + int max_std_level, max_ext_level, std_caps=0, std_caps2=0, ext_caps=0; + long a, c; + + char vendor[13] = "UnknownVndr"; + + __asm__ __volatile__ ( + /* See if CPUID instruction is supported ... */ + /* ... Get copies of EFLAGS into eax and ecx */ + "pushf\n\t" + "pop %0\n\t" + "mov %0, %1\n\t" + + /* ... Toggle the ID bit in one copy and store */ + /* to the EFLAGS reg */ + "xor $0x200000, %0\n\t" + "push %0\n\t" + "popf\n\t" + + /* ... Get the (hopefully modified) EFLAGS */ + "pushf\n\t" + "pop %0\n\t" + : "=a" (a), "=c" (c) + : + : "cc" + ); + + if (a == c) + return 0; /* CPUID not supported */ + + cpuid(0, max_std_level, ebx, ecx, edx); + + /* highest cpuid is 0, no standard features */ + if (max_std_level == 0) + return rval; + + /* save the vendor string */ + *(int *)vendor = ebx; + *(int *)&vendor[4] = edx; + *(int *)&vendor[8] = ecx; + + if (max_std_level >= 1){ + cpuid(1, eax, ebx, std_caps2, std_caps); + if (std_caps & (1<<15)) + rval |= MM_CMOVE; + if (std_caps & (1<<23)) + rval |= MM_MMX; + if (std_caps & (1<<25)) + rval |= MM_MMXEXT | MM_SSE; + if (std_caps & (1<<26)) + rval |= MM_SSE2; + } + + cpuid(0x80000000, max_ext_level, ebx, ecx, edx); + + if (max_ext_level >= 0x80000001) { + cpuid(0x80000001, eax, ebx, ecx, ext_caps); + } + + cpuid(0, eax, ebx, ecx, edx); + if (strcmp(vendor, "AuthenticAMD") == 0) { + /* AMD */ + if (ext_caps & (1<<22)) + rval |= MM_MMXEXT; + if (ext_caps & (1<<31)) + rval |= MM_3DNOW; + if (ext_caps & (1<<30)) + rval |= MM_3DNOWEXT; + if (std_caps2 & (1<<0)) + rval |= MM_SSE3; + } else if (strcmp(vendor, "CentaurHauls") == 0) { + /* VIA C3 */ + if (ext_caps & (1<<24)) + rval |= MM_MMXEXT; + } else if (strcmp(vendor, "CyrixInstead") == 0) { + /* Cyrix */ + if (ext_caps & (1<<24)) + rval |= MM_MMXEXT; + } +#if 0 + av_log(NULL, AV_LOG_DEBUG, "%s%s%s%s%s%s\n", + (rval&MM_MMX) ? "MMX ":"", + (rval&MM_MMXEXT) ? "MMX2 ":"", + (rval&MM_SSE) ? "SSE ":"", + (rval&MM_SSE2) ? "SSE2 ":"", + (rval&MM_3DNOW) ? "3DNow ":"", + (rval&MM_3DNOWEXT) ? "3DNowExt ":""); +#endif +#endif /* ARCH_X86(_64) */ + return rval; +} + + +int ac_mmflag(void) +{ + //if (mm_flag==-1) { + mm_flag = mm_support(); +#ifdef ARCH_X86 + mm_flag |= MM_IA32ASM; +#endif +#ifdef ARCH_X86_64 + mm_flag |= MM_AMD64ASM; +#endif + //} + return(mm_flag); +} + +void ac_mmtest() +{ + mm_flag=-1; + int cc=ac_mmflag(); + return; + printf("(%s) available multimedia extensions:", __FILE__); + + if(cc & MM_SSE3) { + printf(" sse3\n"); + return; + } else if(cc & MM_SSE2) { + printf(" sse2\n"); + return; + } else if(cc & MM_SSE) { + printf(" sse\n"); + return; + } else if(cc & MM_3DNOWEXT) { + printf(" 3dnowext\n"); + return; + } else if(cc & MM_3DNOW) { + printf(" 3dnow\n"); + return; + } else if(cc & MM_MMXEXT) { + printf(" mmxext\n"); + return; + } else if(cc & MM_MMX) { + printf(" mmx\n"); + return; + } else if(cc & MM_AMD64ASM) { + printf(" 64asm\n"); + return; + } else if(cc & MM_IA32ASM) { + printf(" 32asm\n"); + return; + } else printf(" C\n"); +} + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} + +char *ac_mmstr(int flag, int mode) +{ + static char mmstr[64]=""; + int cc; + + if(flag==-1) + //get full mm caps + cc=ac_mmflag(); + else + cc=flag; + + //return max supported mm extensions, or str for user provided flag + if(mode==0) { + if(cc & MM_SSE3) { + return("sse3"); + } else if(cc & MM_SSE2) { + return("sse2"); + } else if(cc & MM_SSE) { + return("sse"); + } else if(cc & MM_3DNOWEXT) { + return("3dnowext"); + } else if(cc & MM_3DNOW) { + return("3dnow"); + } else if(cc & MM_MMXEXT) { + return("mmxext"); + } else if(cc & MM_MMX) { + return("mmx"); + } else if(cc & (MM_AMD64ASM|MM_IA32ASM)) { + return("asm"); + } else return("C"); + } + + //return full capability list + if(mode==1) { + if(cc & MM_SSE3) strlcat(mmstr, "sse3 ", sizeof(mmstr)); + if(cc & MM_SSE2) strlcat(mmstr, "sse2 ", sizeof(mmstr)); + if(cc & MM_SSE) strlcat(mmstr, "sse ", sizeof(mmstr)); + if(cc & MM_3DNOWEXT) strlcat(mmstr, "3dnowext ", sizeof(mmstr)); + if(cc & MM_3DNOW) strlcat(mmstr, "3dnow ", sizeof(mmstr)); + if(cc & MM_MMXEXT) strlcat(mmstr, "mmxext ", sizeof(mmstr)); + if(cc & MM_MMX) strlcat(mmstr, "mmx ", sizeof(mmstr)); + if(cc & (MM_AMD64ASM|MM_IA32ASM)) strlcat(mmstr, "asm ", sizeof(mmstr)); + strlcat(mmstr, "C", sizeof(mmstr)); + return(mmstr); + } + + return(""); +} |