123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- /*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #ifndef SkCpu_DEFINED
- #define SkCpu_DEFINED
- #include "include/core/SkTypes.h"
- struct SkCpu {
- enum {
- SSE1 = 1 << 0,
- SSE2 = 1 << 1,
- SSE3 = 1 << 2,
- SSSE3 = 1 << 3,
- SSE41 = 1 << 4,
- SSE42 = 1 << 5,
- AVX = 1 << 6,
- F16C = 1 << 7,
- FMA = 1 << 8,
- AVX2 = 1 << 9,
- BMI1 = 1 << 10,
- BMI2 = 1 << 11,
- // Handy alias for all the cool Haswell+ instructions.
- HSW = AVX2 | BMI1 | BMI2 | F16C | FMA,
- AVX512F = 1 << 12,
- AVX512DQ = 1 << 13,
- AVX512IFMA = 1 << 14,
- AVX512PF = 1 << 15,
- AVX512ER = 1 << 16,
- AVX512CD = 1 << 17,
- AVX512BW = 1 << 18,
- AVX512VL = 1 << 19,
- // Handy alias for all the cool Skylake Xeon+ instructions.
- SKX = AVX512F | AVX512DQ | AVX512CD | AVX512BW | AVX512VL,
- };
- enum {
- NEON = 1 << 0,
- NEON_FMA = 1 << 1,
- VFP_FP16 = 1 << 2,
- CRC32 = 1 << 3,
- ASIMDHP = 1 << 4,
- };
- static void CacheRuntimeFeatures();
- static bool Supports(uint32_t);
- private:
- static uint32_t gCachedFeatures;
- };
- inline bool SkCpu::Supports(uint32_t mask) {
- uint32_t features = gCachedFeatures;
- // If we mask in compile-time known lower limits, the compiler can
- // often compile away this entire function.
- #if SK_CPU_X86
- #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1
- features |= SSE1;
- #endif
- #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
- features |= SSE2;
- #endif
- #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE3
- features |= SSE3;
- #endif
- #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
- features |= SSSE3;
- #endif
- #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE41
- features |= SSE41;
- #endif
- #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE42
- features |= SSE42;
- #endif
- #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_AVX
- features |= AVX;
- #endif
- // F16C goes here if we add SK_CPU_SSE_LEVEL_F16C
- #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_AVX2
- features |= AVX2;
- #endif
- // FMA doesn't fit neatly into this total ordering.
- // It's available on Haswell+ just like AVX2, but it's technically a different bit.
- // TODO: circle back on this if we find ourselves limited by lack of compile-time FMA
- #if defined(SK_CPU_LIMIT_SSE41)
- features &= (SkCpu::SSE1 | SkCpu::SSE2 | SkCpu::SSE3 | SkCpu::SSSE3 | SkCpu::SSE41);
- #elif defined(SK_CPU_LIMIT_SSE2)
- features &= (SkCpu::SSE1 | SkCpu::SSE2);
- #endif
- #else
- #if defined(SK_ARM_HAS_NEON)
- features |= NEON;
- #endif
- #if defined(SK_CPU_ARM64)
- features |= NEON|NEON_FMA|VFP_FP16;
- #endif
- #if defined(SK_ARM_HAS_CRC32)
- features |= CRC32;
- #endif
- #endif
- return (features & mask) == mask;
- }
- #endif//SkCpu_DEFINED
|