| Android NDK CPU Features detection library: |
| ==== |
| |
| This NDK provides a small library named "`cpufeatures`" that can be used at |
| runtime to detect the target device's CPU family and the optional features |
| it supports. |
| |
| Usage: |
| ------ |
| |
| The library is available as an import module. To use it, you must: |
| |
| * List '`cpufeatures`' in your list of static library dependencies, as in: |
| |
| LOCAL_STATIC_LIBRARIES := cpufeatures |
| |
| * At the end of your Android.mk, import the '`android/cpufeatures`' module, |
| as in: |
| |
| $(call import-module,android/cpufeatures) |
| |
| * In your source code, include the header named `<cpu-features.h>` |
| |
| |
| Here is a simple example: |
| |
| <project-path>/jni/Android.mk: |
| LOCAL_PATH := $(call my-dir) |
| |
| include $(CLEAR_VARS) |
| LOCAL_MODULE := <your-module-name> |
| LOCAL_SRC_FILES := <your-source-files> |
| LOCAL_STATIC_LIBRARIES := cpufeatures |
| include $(BUILD_SHARED_LIBRARY) |
| |
| $(call import-module,android/cpufeatures) |
| |
| |
| Features: |
| --------- |
| |
| Two functions are provided for now: |
| |
| AndroidCpuFamily android_getCpuFamily(); |
| |
| Returns a value matching the CPU family/architecture supported by the |
| current process as an enum. Currently, the following families are defined: |
| |
| * `ANDROID_CPU_FAMILY_ARM` |
| |
| * `ANDROID_CPU_FAMILY_X86` |
| |
| * `ANDROID_CPU_FAMILY_MIPS` |
| |
| * `ANDROID_CPU_FAMILY_ARM64` |
| |
| * `ANDROID_CPU_FAMILY_X86_64` |
| |
| * `ANDROID_CPU_FAMILY_MIPS64` |
| |
| Note that when running a 32-bit executable on a 64-bit system, this function |
| will return the 32-bit family value only. |
| |
| Secondly: |
| |
| uint64_t android_getCpuFeatures(); |
| |
| Returns the set of optional features supported by the device's CPU. |
| The result is a set of bit-flags, each corresponding to one CPU |
| Family-specific optional feature. |
| |
| Currently, only the following flags are defined, for the 32-bit ARM CPU |
| Family: |
| |
| * `ANDROID_CPU_ARM_FEATURE_VFPv2` |
| > Indicates that the device's CPU supports VFPv2 instruction set. |
| Most ARMv6 CPUs support these. |
| |
| * `ANDROID_CPU_ARM_FEATURE_ARMv7` |
| > Indicates that the device's CPU supports the ARMv7-A instruction |
| set as supported by the "armeabi-v7a" abi (see CPU-ARCH-ABIS.html). |
| This corresponds to Thumb-2 and VFPv3-D16 instructions. |
| |
| * `ANDROID_CPU_ARM_FEATURE_VFPv3` |
| > Indicates that the device's CPU supports the VFPv3 hardware FPU |
| instruction set extension. Due to the definition of 'armeabi-v7a', |
| this will always be the case if ANDROID_CPU_ARM_FEATURE_ARMv7 is |
| returned. |
| |
| Note that this corresponds to the minimum profile VFPv3-D16 that |
| _only_ provides 16 hardware double-precision FP registers. |
| |
| * `ANDROID_CPU_ARM_FEATURE_VFP_D32` |
| > Indicates that the device's CPU supports 32 hardware double-precision |
| FP registers instead of 16. Note that there are still only 32 single- |
| precision registers mapped to the same register banks. |
| |
| * `ANDROID_CPU_ARM_FEATURE_NEON` |
| > Indicates that the device's CPU supports the ARM Advanced SIMD |
| (a.k.a. NEON) vector instruction set extension. Note that ARM |
| mandates that such CPUs also implement VFPv3-D32, which provides |
| 32 hardware FP registers (shared with the NEON unit). |
| |
| * `ANDROID_CPU_ARM_FEATURE_VFP_FP16` |
| > Indicates that the device's CPU supports instructions to perform |
| floating-point operations on 16-bit registers. This is part of the |
| VFPv4 specification. |
| |
| * `ANDROID_CPU_ARM_FEATURE_VFP_FMA` |
| > Indicates that the device's CPU supports fused multiply-accumulate |
| VFP instructions extension. Also part of the VFPv4 specification. |
| |
| * `ANDROID_CPU_ARM_FEATURE_NEON_FMA` |
| > Indicates that the device's CPU supports fused multiply-accumulate |
| NEON instructions extension. Also part of the VFPv4 specification. |
| |
| * `ANDROID_CPU_ARM_FEATURE_IDIV_ARM` |
| > Indicates that the device's CPU supports Integer division in ARM mode. |
| Only available on recent CPUs (e.g. Cortex-A15). |
| |
| * `ANDROID_CPU_ARM_FEATURE_IDIV_THUMB2` |
| > Indicates that the device's CPU supports Integer division in Thumb-2 |
| mode. Only available on recent CPUs (e.g. Cortex-A15). |
| |
| * `ANDROID_CPU_ARM_FEATURE_iWMMXt` |
| > Indicates that the device's CPU supports extension that adds MMX |
| registers and instructions. This is only available on a few XScale- |
| based CPU. |
| |
| * `ANDROID_CPU_ARM_FEATURE_LDREX_STREX` |
| > Indicates that the device's CPU supports LDREX and STREX instructions |
| available since ARMv6. Together they provide atomic update on memory |
| with the help of exclusive monitor. |
| |
| And the following flags for the 32-bit x86 CPU Family: |
| |
| * `ANDROID_CPU_X86_FEATURE_SSSE3` |
| > Indicates that the device's CPU supports the SSSE3 instruction |
| extension set. Note that this is unlike SSE3 which is required |
| by the x86 NDK ABI. |
| |
| * `ANDROID_CPU_X86_FEATURE_POPCNT` |
| > Indicates that the device's CPU supports the POPCNT instruction. |
| |
| * `ANDROID_CPU_X86_FEATURE_MOVBE` |
| > Indicates that the device's CPU supports the MOVBE instruction. |
| This one is specific to some Intel IA-32 CPUs, like the Atom. |
| |
| Other CPU families do not have extensions listed at the moment, which |
| means that android_getCpuFeatures() will return 0 for them. |
| |
| The following function is also defined to return the max number of |
| CPU cores on the target device: |
| |
| int android_getCpuCount(void); |
| |
| |
| Important Note: |
| --------------- |
| |
| The cpufeatures library will be updated to support more CPU families and |
| optional features in the future. It is designed to work as-is on all |
| official Android platform versions. |
| |
| |
| Change History: |
| --------------- |
| |
| Please see the comments in `$NDK/sources/android/cpufeatures/cpu-features.c` |
| for the complete change history for this library. |