00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023 #include <inttypes.h>
00024
00025 #include "cpu_accel.h"
00026
00027 #ifdef X86_CPU
00028 static int x86_accel (void)
00029 {
00030 int eax, ebx, ecx, edx;
00031 int AMD;
00032 int caps;
00033
00034 #define cpuid(op,eax,ebx,ecx,edx) \
00035 asm ("cpuid" \
00036 : "=a" (eax), \
00037 "=b" (ebx), \
00038 "=c" (ecx), \
00039 "=d" (edx) \
00040 : "a" (op) \
00041 : "cc")
00042
00043 asm ("pushfl\n\t"
00044 "popl %0\n\t"
00045 "movl %0,%1\n\t"
00046 "xorl $0x200000,%0\n\t"
00047 "pushl %0\n\t"
00048 "popfl\n\t"
00049 "pushfl\n\t"
00050 "popl %0"
00051 : "=a" (eax),
00052 "=b" (ebx)
00053 :
00054 : "cc");
00055
00056 if (eax == ebx)
00057 return 0;
00058
00059 cpuid (0x00000000, eax, ebx, ecx, edx);
00060 if (!eax)
00061 return 0;
00062
00063 AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65);
00064
00065 cpuid (0x00000001, eax, ebx, ecx, edx);
00066 if (! (edx & 0x00800000))
00067 return 0;
00068
00069 caps = ACCEL_X86_MMX;
00070 if (edx & 0x02000000)
00071 caps = ACCEL_X86_MMX | ACCEL_X86_MMXEXT;
00072
00073 cpuid (0x80000000, eax, ebx, ecx, edx);
00074 if (eax < 0x80000001)
00075 return caps;
00076
00077 cpuid (0x80000001, eax, ebx, ecx, edx);
00078
00079 if (edx & 0x80000000)
00080 caps |= ACCEL_X86_3DNOW;
00081
00082 if (AMD && (edx & 0x00400000))
00083 {
00084 caps |= ACCEL_X86_MMXEXT;
00085 }
00086
00087 return caps;
00088 }
00089 #endif
00090
00091 int cpu_accel (void)
00092 {
00093 #ifdef X86_CPU
00094 static int got_accel = 0;
00095 static int accel;
00096
00097 if (!got_accel) {
00098 got_accel = 1;
00099 accel = x86_accel ();
00100 }
00101
00102 return accel;
00103 #else
00104 return 0;
00105 #endif
00106 }