From 6ce23c57dfeae2e3bb21d31c5f0953968bc7d39f Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 2 Nov 2012 21:25:54 +0100 Subject: [PATCH] Fix x86_cpuid to preserve ebx for PIC. --- performance.c | 40 +++++++++++++++++++++------------------- performance.h | 1 - retroarch.c | 20 +++++++++++--------- 3 files changed, 32 insertions(+), 29 deletions(-) diff --git a/performance.c b/performance.c index 55291b3c31..c56fe5936f 100644 --- a/performance.c +++ b/performance.c @@ -105,14 +105,24 @@ rarch_perf_tick_t rarch_get_perf_counter(void) #ifdef CPU_X86 static void x86_cpuid(int func, int flags[4]) { -#if defined(__GNUC__) && !defined(ANDROID) - /* doesn't compile on x86 Android - - * error - inconsistent operand constraints in an 'asm' */ - asm volatile("cpuid\n" : - "=a"(flags[0]), - "=b"(flags[1]), - "=c"(flags[2]), - "=d"(flags[3]) : "a"(func)); + // On Android, we compile RetroArch with PIC, and we are not allowed to clobber the ebx + // register. +#ifdef __x86_64__ +#define REG_b "rbx" +#define REG_S "rsi" +#else +#define REG_b "ebx" +#define REG_S "esi" +#endif + +#if defined(__GNUC__) + asm volatile ( + "mov %%"REG_b", %%"REG_S"\n" + "cpuid\n" + "xchg %%"REG_b", %%"REG_S"\n" + : "=a"(flags[0]), "=S"(flags[1]), "=c"(flags[2]), "=d"(flags[3]) + : "a"(func)); + #elif defined(_MSC_VER) __cpuid(flags, func); #endif @@ -123,11 +133,7 @@ void rarch_get_cpu_features(struct rarch_cpu_features *cpu) { memset(cpu, 0, sizeof(*cpu)); -#if defined(ANDROID) - uint64_t cpu_flags = android_getCpuFeatures(); -#endif - -#if defined(CPU_X86) && !defined(ANDROID) +#if defined(CPU_X86) int flags[4]; x86_cpuid(0, flags); @@ -149,13 +155,9 @@ void rarch_get_cpu_features(struct rarch_cpu_features *cpu) RARCH_LOG("[CPUID]: SSE: %d\n", cpu->sse); RARCH_LOG("[CPUID]: SSE2: %d\n", cpu->sse2); RARCH_LOG("[CPUID]: AVX: %d\n", cpu->avx); -#endif - -#if defined(ANDROID_ARM) +#elif defined(ANDROID) && defined(ANDROID_ARM) + uint64_t cpu_flags = android_getCpuFeatures(); cpu->neon = (cpu_flags & ANDROID_CPU_ARM_FEATURE_NEON); RARCH_LOG("[CPUID]: NEON: %d\n", cpu->neon); -#elif defined(ANDROID_X86) && defined(HAVE_SSSE3) - cpu->ssse3 = (cpu_flags & ANDROID_CPU_X86_FEATURE_SSSE3); - RARCH_LOG("[CPUID]: SSSE3: %d\n", cpu->ssse3); #endif } diff --git a/performance.h b/performance.h index ca098aba16..a712061546 100644 --- a/performance.h +++ b/performance.h @@ -44,7 +44,6 @@ struct rarch_cpu_features { bool sse; bool sse2; - bool ssse3; bool vmx; bool avx; bool neon; diff --git a/retroarch.c b/retroarch.c index 6bfb3f24a8..470f7e7deb 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2546,20 +2546,22 @@ static void validate_cpu_features(void) struct rarch_cpu_features cpu; rarch_get_cpu_features(&cpu); +#define FAIL_CPU(simd_type) do { \ + RARCH_ERR(simd_type " code is compiled in, but CPU does not support this feature. Cannot continue.\n"); \ + rarch_fail(1, "validate_cpu_features()"); \ +} while(0) + +#ifdef __SSE__ + if (!cpu.sse) + FAIL_CPU("SSE"); +#endif #ifdef __SSE2__ if (!cpu.sse2) - { - RARCH_ERR("SSE2 code is compiled in, but CPU does not support this feature. Cannot continue.\n"); - rarch_fail(1, "validate_cpu_features()"); - } + FAIL_CPU("SSE2"); #endif - #ifdef __AVX__ if (!cpu.avx) - { - RARCH_ERR("AVX code is compiled in, but CPU does not support this feature. Cannot continue.\n"); - rarch_fail(1, "validate_cpu_features()"); - } + FAIL_CPU("AVX"); #endif }