#ifndef HIGHWAYHASH_HH_BUFFER_H_
#define HIGHWAYHASH_HH_BUFFER_H_
#include "highwayhash/vector128.h"
#ifndef HH_DISABLE_TARGET_SPECIFIC
namespace highwayhash {
namespace HH_TARGET_NAME {
template <uint32_t kSizeOffset> struct IntMask {};
template <> struct IntMask<0> {
HH_INLINE V4x32U operator()(const V4x32U &size) const {
return V4x32U(_mm_cmpgt_epi32(size, V4x32U(15, 11, 7, 3)));
}
};
template <> struct IntMask<16> {
HH_INLINE V4x32U operator()(const V4x32U &size) const {
return V4x32U(_mm_cmpgt_epi32(size, V4x32U(31, 27, 23, 19)));
}
};
HH_INLINE V4x32U Insert4AboveMask(const uint32_t bytes4, const V4x32U &mask,
const V4x32U &prev) {
return prev | AndNot(mask, V4x32U(bytes4));
}
HH_INLINE V4x32U Concatenate(const V4x32U &prefix, const size_t prefix_len,
const V4x32U &suffix) {
static const uint64_t table[V16x8U::N][V2x64U::N] = {
{0x0706050403020100ull, 0x0F0E0D0C0B0A0908ull},
{0x06050403020100FFull, 0x0E0D0C0B0A090807ull},
{0x050403020100FFFFull, 0x0D0C0B0A09080706ull},
{0x0403020100FFFFFFull, 0x0C0B0A0908070605ull},
{0x03020100FFFFFFFFull, 0x0B0A090807060504ull},
{0x020100FFFFFFFFFFull, 0x0A09080706050403ull},
{0x0100FFFFFFFFFFFFull, 0x0908070605040302ull},
{0x00FFFFFFFFFFFFFFull, 0x0807060504030201ull},
{0xFFFFFFFFFFFFFFFFull, 0x0706050403020100ull},
{0xFFFFFFFFFFFFFFFFull, 0x06050403020100FFull},
{0xFFFFFFFFFFFFFFFFull, 0x050403020100FFFFull},
{0xFFFFFFFFFFFFFFFFull, 0x0403020100FFFFFFull},
{0xFFFFFFFFFFFFFFFFull, 0x03020100FFFFFFFFull},
{0xFFFFFFFFFFFFFFFFull, 0x020100FFFFFFFFFFull},
{0xFFFFFFFFFFFFFFFFull, 0x0100FFFFFFFFFFFFull},
{0xFFFFFFFFFFFFFFFFull, 0x00FFFFFFFFFFFFFFull}};
const V2x64U control = Load<V2x64U>(&table[prefix_len][0]);
const V2x64U shifted_suffix(_mm_shuffle_epi8(suffix, control));
return V4x32U(_mm_blendv_epi8(shifted_suffix, prefix, control));
}
} }
#endif #endif