forked from simdjson/simdjson
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimd_input.h
More file actions
87 lines (69 loc) · 2.43 KB
/
Copy pathsimd_input.h
File metadata and controls
87 lines (69 loc) · 2.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#ifndef SIMDJSON_HASWELL_SIMD_INPUT_H
#define SIMDJSON_HASWELL_SIMD_INPUT_H
#include "../simd_input.h"
#ifdef IS_X86_64
TARGET_HASWELL
namespace simdjson {
template <>
struct simd_input<Architecture::HASWELL> {
__m256i chunks[2];
really_inline simd_input() : chunks{__m256i(), __m256i()} {}
really_inline simd_input(const __m256i chunk0, const __m256i chunk1)
: chunks{chunk0, chunk1} {}
really_inline simd_input(const uint8_t *ptr)
: chunks{
_mm256_loadu_si256(reinterpret_cast<const __m256i *>(ptr + 0*32)),
_mm256_loadu_si256(reinterpret_cast<const __m256i *>(ptr + 1*32))
} {}
template <typename F>
really_inline void each(F const& each_chunk) const
{
each_chunk(this->chunks[0]);
each_chunk(this->chunks[1]);
}
template <typename F>
really_inline simd_input<Architecture::HASWELL> map(F const& map_chunk) const {
return simd_input<Architecture::HASWELL>(
map_chunk(this->chunks[0]),
map_chunk(this->chunks[1])
);
}
template <typename F>
really_inline simd_input<Architecture::HASWELL> map(const simd_input<Architecture::HASWELL> b, F const& map_chunk) const {
return simd_input<Architecture::HASWELL>(
map_chunk(this->chunks[0], b.chunks[0]),
map_chunk(this->chunks[1], b.chunks[1])
);
}
template <typename F>
really_inline __m256i reduce(F const& reduce_pair) const {
return reduce_pair(this->chunks[0], this->chunks[1]);
}
really_inline uint64_t to_bitmask() const {
uint64_t r_lo = static_cast<uint32_t>(_mm256_movemask_epi8(this->chunks[0]));
uint64_t r_hi = _mm256_movemask_epi8(this->chunks[1]);
return r_lo | (r_hi << 32);
}
really_inline simd_input<Architecture::HASWELL> bit_or(const uint8_t m) const {
const __m256i mask = _mm256_set1_epi8(m);
return this->map( [&](auto a) {
return _mm256_or_si256(a, mask);
});
}
really_inline uint64_t eq(const uint8_t m) const {
const __m256i mask = _mm256_set1_epi8(m);
return this->map( [&](auto a) {
return _mm256_cmpeq_epi8(a, mask);
}).to_bitmask();
}
really_inline uint64_t lteq(const uint8_t m) const {
const __m256i maxval = _mm256_set1_epi8(m);
return this->map( [&](auto a) {
return _mm256_cmpeq_epi8(_mm256_max_epu8(maxval, a), maxval);
}).to_bitmask();
}
}; // struct simd_input
} // namespace simdjson
UNTARGET_REGION
#endif // IS_X86_64
#endif // SIMDJSON_HASWELL_SIMD_INPUT_H