michael@0: /******************************************************************** michael@0: * * michael@0: * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE. * michael@0: * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * michael@0: * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * michael@0: * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * michael@0: * * michael@0: * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2010 * michael@0: * by the Xiph.Org Foundation and contributors http://www.xiph.org/ * michael@0: * * michael@0: ******************************************************************** michael@0: michael@0: CPU capability detection for ARM processors. michael@0: michael@0: function: michael@0: last mod: $Id: cpu.c 17344 2010-07-21 01:42:18Z tterribe $ michael@0: michael@0: ********************************************************************/ michael@0: michael@0: #include "armcpu.h" michael@0: michael@0: #if !defined(OC_ARM_ASM)|| \ michael@0: !defined(OC_ARM_ASM_EDSP)&&!defined(OC_ARM_ASM_ARMV6)&& \ michael@0: !defined(OC_ARM_ASM_NEON) michael@0: ogg_uint32_t oc_cpu_flags_get(void){ michael@0: return 0; michael@0: } michael@0: michael@0: #elif defined(_MSC_VER) michael@0: /*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/ michael@0: # define WIN32_LEAN_AND_MEAN michael@0: # define WIN32_EXTRA_LEAN michael@0: # include michael@0: michael@0: ogg_uint32_t oc_cpu_flags_get(void){ michael@0: ogg_uint32_t flags; michael@0: flags=0; michael@0: /*MSVC has no inline __asm support for ARM, but it does let you __emit michael@0: instructions via their assembled hex code. michael@0: All of these instructions should be essentially nops.*/ michael@0: # if defined(OC_ARM_ASM_EDSP) michael@0: __try{ michael@0: /*PLD [r13]*/ michael@0: __emit(0xF5DDF000); michael@0: flags|=OC_CPU_ARM_EDSP; michael@0: } michael@0: __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ michael@0: /*Ignore exception.*/ michael@0: } michael@0: # if defined(OC_ARM_ASM_MEDIA) michael@0: __try{ michael@0: /*SHADD8 r3,r3,r3*/ michael@0: __emit(0xE6333F93); michael@0: flags|=OC_CPU_ARM_MEDIA; michael@0: } michael@0: __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ michael@0: /*Ignore exception.*/ michael@0: } michael@0: # if defined(OC_ARM_ASM_NEON) michael@0: __try{ michael@0: /*VORR q0,q0,q0*/ michael@0: __emit(0xF2200150); michael@0: flags|=OC_CPU_ARM_NEON; michael@0: } michael@0: __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ michael@0: /*Ignore exception.*/ michael@0: } michael@0: # endif michael@0: # endif michael@0: # endif michael@0: return flags; michael@0: } michael@0: michael@0: #elif defined(__linux__) michael@0: # include michael@0: # include michael@0: # include michael@0: michael@0: ogg_uint32_t oc_cpu_flags_get(void){ michael@0: ogg_uint32_t flags; michael@0: FILE *fin; michael@0: flags=0; michael@0: /*Reading /proc/self/auxv would be easier, but that doesn't work reliably on michael@0: Android. michael@0: This also means that detection will fail in Scratchbox.*/ michael@0: fin=fopen("/proc/cpuinfo","r"); michael@0: if(fin!=NULL){ michael@0: /*512 should be enough for anybody (it's even enough for all the flags that michael@0: x86 has accumulated... so far).*/ michael@0: char buf[512]; michael@0: while(fgets(buf,511,fin)!=NULL){ michael@0: if(memcmp(buf,"Features",8)==0){ michael@0: char *p; michael@0: p=strstr(buf," edsp"); michael@0: if(p!=NULL&&(p[5]==' '||p[5]=='\n'))flags|=OC_CPU_ARM_EDSP; michael@0: p=strstr(buf," neon"); michael@0: if(p!=NULL&&(p[5]==' '||p[5]=='\n'))flags|=OC_CPU_ARM_NEON; michael@0: } michael@0: if(memcmp(buf,"CPU architecture:",17)==0){ michael@0: int version; michael@0: version=atoi(buf+17); michael@0: if(version>=6)flags|=OC_CPU_ARM_MEDIA; michael@0: } michael@0: } michael@0: fclose(fin); michael@0: } michael@0: return flags; michael@0: } michael@0: michael@0: #else michael@0: /*The feature registers which can tell us what the processor supports are michael@0: accessible in priveleged modes only, so we can't have a general user-space michael@0: detection method like on x86.*/ michael@0: # error "Configured to use ARM asm but no CPU detection method available for " \ michael@0: "your platform. Reconfigure with --disable-asm (or send patches)." michael@0: #endif