Coverage Report

Created: 2021-08-22 09:07

/src/skia/src/core/SkCpu.h
Line
Count
Source
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 "include/core/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
        SKX = AVX512F  | AVX512DQ | AVX512CD | AVX512BW | AVX512VL,
41
42
        ERMS       = 1 << 20,
43
    };
44
    enum {
45
        NEON     = 1 << 0,
46
        NEON_FMA = 1 << 1,
47
        VFP_FP16 = 1 << 2,
48
        CRC32    = 1 << 3,
49
        ASIMDHP  = 1 << 4,
50
    };
51
52
    static void CacheRuntimeFeatures();
53
    static bool Supports(uint32_t);
54
private:
55
    static uint32_t gCachedFeatures;
56
};
57
58
10
inline bool SkCpu::Supports(uint32_t mask) {
59
10
    uint32_t features = gCachedFeatures;
60
61
    // If we mask in compile-time known lower limits, the compiler can
62
    // often compile away this entire function.
63
10
#if SK_CPU_X86
64
10
    #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1
65
10
    features |= SSE1;
66
10
    #endif
67
10
    #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
68
10
    features |= SSE2;
69
10
    #endif
70
    #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE3
71
    features |= SSE3;
72
    #endif
73
    #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSSE3
74
    features |= SSSE3;
75
    #endif
76
    #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE41
77
    features |= SSE41;
78
    #endif
79
    #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE42
80
    features |= SSE42;
81
    #endif
82
    #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_AVX
83
    features |= AVX;
84
    #endif
85
    // F16C goes here if we add SK_CPU_SSE_LEVEL_F16C
86
    #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_AVX2
87
    features |= AVX2;
88
    #endif
89
    #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SKX
90
    features |= (AVX512F | AVX512DQ | AVX512CD | AVX512BW | AVX512VL);
91
    #endif
92
    // FMA doesn't fit neatly into this total ordering.
93
    // It's available on Haswell+ just like AVX2, but it's technically a different bit.
94
    // TODO: circle back on this if we find ourselves limited by lack of compile-time FMA
95
96
    #if defined(SK_CPU_LIMIT_AVX)
97
    features &= (SSE1 | SSE2 | SSE3 | SSSE3 | SSE41 | SSE42 | AVX);
98
    #elif defined(SK_CPU_LIMIT_SSE41)
99
    features &= (SSE1 | SSE2 | SSE3 | SSSE3 | SSE41);
100
    #elif defined(SK_CPU_LIMIT_SSE2)
101
    features &= (SSE1 | SSE2);
102
    #endif
103
104
#else
105
    #if defined(SK_ARM_HAS_NEON)
106
    features |= NEON;
107
    #endif
108
109
    #if defined(SK_CPU_ARM64)
110
    features |= NEON|NEON_FMA|VFP_FP16;
111
    #endif
112
113
    #if defined(SK_ARM_HAS_CRC32)
114
    features |= CRC32;
115
    #endif
116
117
#endif
118
10
    return (features & mask) == mask;
119
10
}
120
121
#endif//SkCpu_DEFINED