Coverage Report

Created: 2024-05-20 07:14

/src/skia/src/core/SkCpu.h
Line
Count
Source (jump to first uncovered line)
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
#include <cstdint>
14
15
struct SkCpu {
16
    enum {
17
        SSE1       = 1 << 0,
18
        SSE2       = 1 << 1,
19
        SSE3       = 1 << 2,
20
        SSSE3      = 1 << 3,
21
        SSE41      = 1 << 4,
22
        SSE42      = 1 << 5,
23
        AVX        = 1 << 6,
24
        F16C       = 1 << 7,
25
        FMA        = 1 << 8,
26
        AVX2       = 1 << 9,
27
        BMI1       = 1 << 10,
28
        BMI2       = 1 << 11,
29
        // Handy alias for all the cool Haswell+ instructions.
30
        HSW = AVX2 | BMI1 | BMI2 | F16C | FMA,
31
32
        AVX512F    = 1 << 12,
33
        AVX512DQ   = 1 << 13,
34
        AVX512IFMA = 1 << 14,
35
        AVX512PF   = 1 << 15,
36
        AVX512ER   = 1 << 16,
37
        AVX512CD   = 1 << 17,
38
        AVX512BW   = 1 << 18,
39
        AVX512VL   = 1 << 19,
40
41
        // Handy alias for all the cool Skylake Xeon+ instructions.
42
        SKX = AVX512F  | AVX512DQ | AVX512CD | AVX512BW | AVX512VL,
43
44
        ERMS       = 1 << 20,
45
    };
46
47
    enum {
48
        LOONGARCH_SX = 1 << 0,
49
        LOONGARCH_ASX = 1 << 1,
50
    };
51
52
    static void CacheRuntimeFeatures();
53
    static bool Supports(uint32_t);
54
private:
55
    static uint32_t gCachedFeatures;
56
};
57
58
0
inline bool SkCpu::Supports(uint32_t mask) {
59
0
    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
0
#if SK_CPU_X86
64
0
    #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE1
65
0
    features |= SSE1;
66
0
    #endif
67
0
    #if SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2
68
0
    features |= SSE2;
69
0
    #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
#elif SK_CPU_LOONGARCH
105
    #if SK_CPU_LSX_LEVEL >= SK_CPU_LSX_LEVEL_LSX
106
    features |= LOONGARCH_SX;
107
    #endif
108
    #if SK_CPU_LSX_LEVEL >= SK_CPU_LSX_LEVEL_LASX
109
    features |= LOONGARCH_ASX;
110
    #endif
111
112
#endif
113
0
    return (features & mask) == mask;
114
0
}
115
116
#endif//SkCpu_DEFINED