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