1 2/* 3 * Copyright 2012 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9#ifndef SkUtilsArm_DEFINED 10#define SkUtilsArm_DEFINED 11 12#include "SkUtils.h" 13 14// Define SK_ARM_NEON_MODE to one of the following values 15// corresponding respectively to: 16// - No ARM Neon support at all (not targetting ARMv7-A, or don't have NEON) 17// - Full ARM Neon support (i.e. assume the CPU always supports it) 18// - Optional ARM Neon support (i.e. probe CPU at runtime) 19// 20#define SK_ARM_NEON_MODE_NONE 0 21#define SK_ARM_NEON_MODE_ALWAYS 1 22#define SK_ARM_NEON_MODE_DYNAMIC 2 23 24#if defined(SK_CPU_ARM32) && defined(__ARM_HAVE_OPTIONAL_NEON_SUPPORT) 25# define SK_ARM_NEON_MODE SK_ARM_NEON_MODE_DYNAMIC 26#elif defined(SK_CPU_ARM32) && defined(__ARM_HAVE_NEON) || defined(SK_CPU_ARM64) 27# define SK_ARM_NEON_MODE SK_ARM_NEON_MODE_ALWAYS 28#else 29# define SK_ARM_NEON_MODE SK_ARM_NEON_MODE_NONE 30#endif 31 32// Convenience test macros, always defined as 0 or 1 33#define SK_ARM_NEON_IS_NONE (SK_ARM_NEON_MODE == SK_ARM_NEON_MODE_NONE) 34#define SK_ARM_NEON_IS_ALWAYS (SK_ARM_NEON_MODE == SK_ARM_NEON_MODE_ALWAYS) 35#define SK_ARM_NEON_IS_DYNAMIC (SK_ARM_NEON_MODE == SK_ARM_NEON_MODE_DYNAMIC) 36 37// The sk_cpu_arm_has_neon() function returns true iff the target device 38// is ARMv7-A and supports Neon instructions. In DYNAMIC mode, this actually 39// probes the CPU at runtime (and caches the result). 40 41#if SK_ARM_NEON_IS_NONE 42static inline bool sk_cpu_arm_has_neon(void) { 43 return false; 44} 45#elif SK_ARM_NEON_IS_ALWAYS 46static inline bool sk_cpu_arm_has_neon(void) { 47 return true; 48} 49#else // SK_ARM_NEON_IS_DYNAMIC 50 51extern bool sk_cpu_arm_has_neon(void) SK_PURE_FUNC; 52#endif 53 54// Use SK_ARM_NEON_WRAP(symbol) to map 'symbol' to a NEON-specific symbol 55// when applicable. This will transform 'symbol' differently depending on 56// the current NEON configuration, i.e.: 57// 58// NONE -> 'symbol' 59// ALWAYS -> 'symbol_neon' 60// DYNAMIC -> 'symbol' or 'symbol_neon' depending on runtime check. 61// 62// The goal is to simplify user code, for example: 63// 64// return SK_ARM_NEON_WRAP(do_something)(params); 65// 66// Replaces the equivalent: 67// 68// #if SK_ARM_NEON_IS_NONE 69// return do_something(params); 70// #elif SK_ARM_NEON_IS_ALWAYS 71// return do_something_neon(params); 72// #elif SK_ARM_NEON_IS_DYNAMIC 73// if (sk_cpu_arm_has_neon()) 74// return do_something_neon(params); 75// else 76// return do_something(params); 77// #endif 78// 79#if SK_ARM_NEON_IS_NONE 80# define SK_ARM_NEON_WRAP(x) (x) 81#elif SK_ARM_NEON_IS_ALWAYS 82# define SK_ARM_NEON_WRAP(x) (x ## _neon) 83#elif SK_ARM_NEON_IS_DYNAMIC 84# define SK_ARM_NEON_WRAP(x) (sk_cpu_arm_has_neon() ? x ## _neon : x) 85#endif 86 87#endif // SkUtilsArm_DEFINED 88