Line data Source code
1 : /*
2 : * Copyright 2016 Google Inc.
3 : *
4 : * Use of this source code is governed by a BSD-style license that can be
5 : * found in the LICENSE file.
6 : */
7 :
8 : #ifndef SkCpu_DEFINED
9 : #define SkCpu_DEFINED
10 :
11 : #include "SkTypes.h"
12 :
13 : struct SkCpu {
14 : enum {
15 : SSE1 = 1 << 0,
16 : SSE2 = 1 << 1,
17 : SSE3 = 1 << 2,
18 : SSSE3 = 1 << 3,
19 : SSE41 = 1 << 4,
20 : SSE42 = 1 << 5,
21 : AVX = 1 << 6,
22 : F16C = 1 << 7,
23 : FMA = 1 << 8,
24 : AVX2 = 1 << 9,
25 : BMI1 = 1 << 10,
26 : BMI2 = 1 << 11,
27 : // Handy alias for all the cool Haswell+ instructions.
28 : HSW = AVX2 | BMI1 | BMI2 | F16C | FMA,
29 :
30 : AVX512F = 1 << 12,
31 : AVX512DQ = 1 << 13,
32 : AVX512IFMA = 1 << 14,
33 : AVX512PF = 1 << 15,
34 : AVX512ER = 1 << 16,
35 : AVX512CD = 1 << 17,
36 : AVX512BW = 1 << 18,
37 : AVX512VL = 1 << 19,
38 :
39 : // Handy alias for all the cool Skylake Xeon+ instructions.
40 : SKY = AVX512F | AVX512DQ | AVX512CD | AVX512BW | AVX512VL,
41 : };
42 : enum {
43 : NEON = 1 << 0,
44 : NEON_FMA = 1 << 1,
45 : VFP_FP16 = 1 << 2,
46 : CRC32 = 1 << 3,
47 : };
48 :
49 : static void CacheRuntimeFeatures();
50 : static bool Supports(uint32_t);
51 : private:
52 : static uint32_t gCachedFeatures;
53 : };
54 :
55 1044 : inline bool SkCpu::Supports(uint32_t mask) {
56 1044 : uint32_t features = gCachedFeatures;
57 :
58 : // If we mask in compile-time known lower limits, the compiler can
59 : // often compile away this entire function.
60 : #if SK_CPU_X86
61 : #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1
62 1044 : features |= SSE1;
63 : #endif
64 : #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
65 1044 : features |= SSE2;
66 : #endif
67 : #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE3
68 : features |= SSE3;
69 : #endif
70 : #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
71 : features |= SSSE3;
72 : #endif
73 : #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE41
74 : features |= SSE41;
75 : #endif
76 : #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE42
77 : features |= SSE42;
78 : #endif
79 : #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_AVX
80 : features |= AVX;
81 : #endif
82 : // F16C goes here if we add SK_CPU_SSE_LEVEL_F16C
83 : #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_AVX2
84 : features |= AVX2;
85 : #endif
86 : // FMA doesn't fit neatly into this total ordering.
87 : // It's available on Haswell+ just like AVX2, but it's technically a different bit.
88 : // TODO: circle back on this if we find ourselves limited by lack of compile-time FMA
89 :
90 : #else
91 : #if defined(SK_ARM_HAS_NEON)
92 : features |= NEON;
93 : #endif
94 :
95 : #if defined(SK_CPU_ARM64)
96 : features |= NEON|NEON_FMA|VFP_FP16;
97 : #endif
98 :
99 : #if defined(SK_ARM_HAS_CRC32)
100 : features |= CRC32;
101 : #endif
102 :
103 : #endif
104 1044 : return (features & mask) == mask;
105 : }
106 :
107 : #endif//SkCpu_DEFINED
|