xref: /freebsd/contrib/llvm-project/libc/src/__support/HashTable/sse2/bitmask_impl.inc (revision bb722a7d0f1642bff6487f943ad0427799a6e5bf)
1//===-- HashTable BitMasks SSE2 Implementation ------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include <immintrin.h>
10
11#include "src/__support/macros/config.h"
12
13namespace LIBC_NAMESPACE_DECL {
14namespace internal {
15// With SSE2, every bitmask is iteratable as
16// we use single bit to encode the data.
17
18using BitMask = BitMaskAdaptor<uint16_t, 0x1u>;
19using IteratableBitMask = IteratableBitMaskAdaptor<BitMask>;
20
21struct Group {
22  __m128i data;
23
24  // Load a group of control words from an arbitary address.
25  LIBC_INLINE static Group load(const void *addr) {
26    return {_mm_loadu_si128(static_cast<const __m128i *>(addr))};
27  }
28
29  // Load a group of control words from an aligned address.
30  LIBC_INLINE static Group load_aligned(const void *addr) {
31    return {_mm_load_si128(static_cast<const __m128i *>(addr))};
32  }
33
34  // Find out the lanes equal to the given byte and return the bitmask
35  // with corresponding bits set.
36  LIBC_INLINE IteratableBitMask match_byte(uint8_t byte) const {
37    auto cmp = _mm_cmpeq_epi8(data, _mm_set1_epi8(byte));
38    auto bitmask = static_cast<uint16_t>(_mm_movemask_epi8(cmp));
39    return {{bitmask}};
40  }
41
42  LIBC_INLINE BitMask mask_available() const {
43    auto bitmask = static_cast<uint16_t>(_mm_movemask_epi8(data));
44    return {bitmask};
45  }
46
47  LIBC_INLINE IteratableBitMask occupied() const {
48    return {{static_cast<uint16_t>(~mask_available().word)}};
49  }
50};
51} // namespace internal
52} // namespace LIBC_NAMESPACE_DECL
53