2002-11-08 00:02:15 -08:00
|
|
|
#include "evas_common.h"
|
|
|
|
|
|
|
|
#ifdef BUILD_MMX
|
|
|
|
#include "evas_mmx.h"
|
|
|
|
#endif
|
|
|
|
|
2003-03-10 20:39:58 -08:00
|
|
|
static jmp_buf detect_buf;
|
|
|
|
static int cpu_feature_mask = 0;
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_common_cpu_catch_ill(void)
|
|
|
|
{
|
|
|
|
longjmp(detect_buf, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef __i386__
|
|
|
|
void
|
|
|
|
evas_common_cpu_mmx_test(void)
|
|
|
|
{
|
|
|
|
pxor_r2r(mm4, mm4);
|
|
|
|
evas_common_cpu_end_opt();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
evas_common_cpu_sse_test(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif /* __i386__ */
|
|
|
|
|
|
|
|
#ifdef __POWERPC__
|
|
|
|
#ifdef __VEC__
|
|
|
|
void
|
|
|
|
evas_common_cpu_altivec_test(void)
|
|
|
|
{
|
|
|
|
vector unsigned int zero;
|
|
|
|
zero = vec_splat_u32(0);
|
|
|
|
}
|
|
|
|
#endif /* __VEC__ */
|
|
|
|
#endif /* __POWERPC__ */
|
|
|
|
|
|
|
|
#ifdef __SPARC__
|
|
|
|
void
|
|
|
|
evas_common_cpu_vis_test(void)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif /* __SPARC__ */
|
|
|
|
|
|
|
|
int
|
|
|
|
evas_common_cpu_feature_test(void (*feature)(void))
|
|
|
|
{
|
|
|
|
int enabled = 1;
|
|
|
|
struct sigaction act, oact;
|
|
|
|
|
|
|
|
sigaction(SIGILL, &act, &oact);
|
|
|
|
if (setjmp(detect_buf))
|
|
|
|
enabled = 0;
|
|
|
|
else
|
|
|
|
feature();
|
|
|
|
sigaction(SIGILL, &oact, NULL);
|
|
|
|
|
|
|
|
return enabled;
|
|
|
|
}
|
|
|
|
|
2002-11-08 00:02:15 -08:00
|
|
|
void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_cpu_init(void)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
2003-03-10 20:56:46 -08:00
|
|
|
static int called = 0;
|
2003-03-10 20:39:58 -08:00
|
|
|
int enabled;
|
|
|
|
|
2003-03-10 20:56:46 -08:00
|
|
|
if (called) return;
|
|
|
|
called = 1;
|
2003-03-10 20:39:58 -08:00
|
|
|
#ifdef __i386__
|
|
|
|
|
|
|
|
if (evas_common_cpu_feature_test(evas_common_cpu_mmx_test))
|
|
|
|
cpu_feature_mask |= CPU_FEATURE_MMX;
|
|
|
|
|
|
|
|
if (evas_common_cpu_feature_test(evas_common_cpu_sse_test))
|
|
|
|
cpu_feature_mask |= CPU_FEATURE_SSE;
|
|
|
|
|
|
|
|
#endif /* __i386__ */
|
|
|
|
|
|
|
|
#ifdef __POWERPC__
|
|
|
|
#ifdef __VEC__
|
|
|
|
|
|
|
|
if (evas_common_cpu_feature_test(evas_common_cpu_altivec_test))
|
|
|
|
cpu_feature_mask |= CPU_FEATURE_ALTIVEC;
|
|
|
|
|
|
|
|
#endif /* __VEC__ */
|
|
|
|
#endif /* __POWERPC__ */
|
|
|
|
|
|
|
|
#ifdef __SPARC__
|
|
|
|
|
|
|
|
if (evas_common_cpu_feature_test(evas_common_cpu_vis_test))
|
|
|
|
cpu_feature_mask |= CPU_FEATURE_VIS;
|
|
|
|
|
|
|
|
#endif /* __SPARC__ */
|
|
|
|
|
|
|
|
printf("Cpu mask set to %08x\n", cpu_feature_mask);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline int
|
|
|
|
evas_common_cpu_has_feature(unsigned int feature)
|
|
|
|
{
|
|
|
|
return (cpu_feature_mask & feature);
|
2002-11-08 00:02:15 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_cpu_have_cpuid(void)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
#ifdef BUILD_MMX
|
|
|
|
unsigned int have_cpu_id;
|
|
|
|
|
|
|
|
have_cpu_id = 0;
|
|
|
|
have_cpuid(have_cpu_id);
|
|
|
|
return have_cpu_id;
|
|
|
|
#else
|
|
|
|
return 0;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_cpu_can_do(int *mmx, int *sse, int *sse2)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
#ifdef BUILD_MMX
|
|
|
|
#ifndef HARD_CODED_P3
|
|
|
|
#ifndef HARD_CODED_P2
|
|
|
|
static int do_mmx = 0, do_sse = 0, do_sse2 = 0, done = 0;
|
|
|
|
unsigned int have_cpu_id;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef BUILD_MMX
|
|
|
|
*mmx = 0;
|
|
|
|
*sse = 0;
|
|
|
|
*sse2 = 0;
|
|
|
|
return;
|
|
|
|
#else
|
|
|
|
# ifdef HARD_CODED_P3
|
|
|
|
*mmx = 1;
|
|
|
|
*sse = 1;
|
|
|
|
*sse2 = 0;
|
|
|
|
return;
|
|
|
|
# else
|
|
|
|
# ifdef HARD_CODED_P2
|
|
|
|
*mmx = 1;
|
|
|
|
*sse = 0;
|
|
|
|
*sse2 = 0;
|
|
|
|
return;
|
|
|
|
# else
|
|
|
|
if (done)
|
|
|
|
{
|
|
|
|
*mmx = do_mmx;
|
|
|
|
*sse = do_sse;
|
|
|
|
*sse2 = do_sse2;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
# ifdef BUILD_MMX
|
2002-11-13 21:38:10 -08:00
|
|
|
have_cpu_id = evas_common_cpu_have_cpuid();
|
2002-11-08 00:02:15 -08:00
|
|
|
if (have_cpu_id)
|
|
|
|
{
|
|
|
|
unsigned int cpu_id;
|
|
|
|
|
|
|
|
cpu_id = 0;
|
|
|
|
get_cpuid(cpu_id);
|
|
|
|
if (cpu_id & CPUID_MMX) do_mmx = 1;
|
|
|
|
if (cpu_id & CPUID_SSE) do_sse = 1;
|
|
|
|
if (cpu_id & CPUID_SSE2) do_sse2 = 1;
|
|
|
|
}
|
|
|
|
# endif
|
|
|
|
*mmx = do_mmx;
|
|
|
|
*sse = do_sse;
|
|
|
|
*sse2 = do_sse2;
|
|
|
|
done = 1;
|
|
|
|
# endif
|
|
|
|
# endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef BUILD_MMX
|
|
|
|
void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_cpu_end_opt(void)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
emms();
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
void
|
2002-11-13 21:38:10 -08:00
|
|
|
evas_common_cpu_end_opt(void)
|
2002-11-08 00:02:15 -08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|