Coverage Report

Created: 2026-07-12 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/Simd/src/Simd/SimdGather.h
Line
Count
Source
1
/*
2
* Simd Library (http://ermig1979.github.io/Simd).
3
*
4
* Copyright (c) 2011-2024 Yermalayeu Ihar.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
7
* of this software and associated documentation files (the "Software"), to deal
8
* in the Software without restriction, including without limitation the rights
9
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
* copies of the Software, and to permit persons to whom the Software is
11
* furnished to do so, subject to the following conditions:
12
*
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
* SOFTWARE.
23
*/
24
#ifndef __SimdGather_h__
25
#define __SimdGather_h__
26
27
#include "Simd/SimdInit.h"
28
29
namespace Simd
30
{
31
#ifdef SIMD_SSE41_ENABLE
32
    namespace Sse41
33
    {
34
        template<int step> SIMD_INLINE __m128 Gather(const float* ptr)
35
0
        {
36
0
            SIMD_ALIGNED(16) float buf[F];
37
0
            buf[0] = ptr[0 * step];
38
0
            buf[1] = ptr[1 * step];
39
0
            buf[2] = ptr[2 * step];
40
0
            buf[3] = ptr[3 * step];
41
0
            return _mm_load_ps(buf);
42
0
        }
43
44
        template<int step> SIMD_INLINE __m128 Gather(const float* ptr, size_t size)
45
0
        {
46
0
            SIMD_ALIGNED(16) float buf[F];
47
0
            for (size_t i = 0; i < size; ++i)
48
0
                buf[i] = ptr[i * step];
49
0
            return _mm_load_ps(buf);
50
0
        }
51
    }
52
#endif
53
54
#ifdef SIMD_AVX2_ENABLE
55
    namespace Avx2
56
    {
57
        template<int step> SIMD_INLINE __m256 Gather(const float* ptr)
58
0
        {
59
0
            static const __m256i idx = _mm256_setr_epi32(0 * step, 1 * step, 
60
0
                2 * step, 3 * step, 4 * step, 5 * step, 6 * step, 7 * step);
61
0
            return _mm256_i32gather_ps(ptr, idx, 4);
62
0
        }
63
64
        template<int step> SIMD_INLINE __m256 Gather(const float* ptr, size_t size)
65
0
        {
66
0
            SIMD_ALIGNED(32) float buf[F];
67
0
            for (size_t i = 0; i < size; ++i)
68
0
                buf[i] = ptr[i * step];
69
0
            return _mm256_load_ps(buf);
70
0
        }
71
    }
72
#endif
73
74
#ifdef SIMD_AVX512BW_ENABLE
75
    namespace Avx512bw
76
    {
77
        const __m512i K32_GATHER_ANY = SIMD_MM512_SET1_EPI32(1);
78
        const __m512i K32_GATHER_3A = SIMD_MM512_SETR_EPI32(0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 0, 0, 0, 0, 0);
79
        const __m512i K32_GATHER_3B = SIMD_MM512_SETR_EPI32(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 4, 7, 10, 13);
80
81
        template<int period> SIMD_INLINE __m512 Gather(const float * ptr)
82
        {
83
            return _mm512_i32gather_ps(K32_GATHER_ANY, ptr, sizeof(float)*period);
84
        }
85
86
        template<> SIMD_INLINE __m512 Gather<3>(const float * ptr)
87
        {
88
            __m512 s0 = _mm512_loadu_ps(ptr + 0 * F);
89
            __m512 s1 = _mm512_loadu_ps(ptr + 1 * F);
90
            __m512 s2 = _mm512_loadu_ps(ptr + 2 * F);
91
            return _mm512_mask_permutexvar_ps(_mm512_maskz_permutex2var_ps(0xFFFF, s0, K32_GATHER_3A, s1), 0xF800, K32_GATHER_3B, s2);
92
        }
93
    }
94
#endif
95
}
96
#endif