235 static_assert(Bytes >= 0 && Bytes <= 16,
"shift_left_bytes: Bytes must be in [0, 16]");
236#ifdef NEFORCE_SIMD_SSE2
237 return _mm_bslli_si128(v, Bytes);
238#elif defined(NEFORCE_SIMD_NEON)
239 return vextq_u8(::vdupq_n_u8(0), v,
static_cast<int>(16 - Bytes));
242 for (
int i = 0; i < Bytes; ++i) {
245 for (
int i = Bytes; i < 16; ++i) {
246 result.data[i] = v.data[i - Bytes];
265 static_assert(Bytes >= 0 && Bytes <= 16,
"shift_right_bytes: Bytes must be in [0, 16]");
266#ifdef NEFORCE_SIMD_SSE2
267 return _mm_bsrli_si128(v, Bytes);
268#elif defined(NEFORCE_SIMD_NEON)
269 return vextq_u8(v, ::vdupq_n_u8(0),
static_cast<int>(Bytes));
272 for (
int i = 0; i < 16 - Bytes; ++i) {
273 result.data[i] = v.data[i + Bytes];
275 for (
int i = 16 - Bytes; i < 16; ++i) {
293#if defined(NEFORCE_SIMD_SSSE3) || defined(NEFORCE_SIMD_AVX2)
294 const ::__m128i low_nibble = ::_mm_and_si128(v, ::_mm_set1_epi8(0x0F));
295 const ::__m128i high_nibble = ::_mm_and_si128(::_mm_srli_epi16(v, 4), ::_mm_set1_epi8(0x0F));
296 const ::__m128i lookup = ::_mm_setr_epi8(0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4);
297 const ::__m128i pop_low = ::_mm_shuffle_epi8(lookup, low_nibble);
298 const ::__m128i pop_high = ::_mm_shuffle_epi8(lookup, high_nibble);
299 const ::__m128i pop8 = ::_mm_add_epi8(pop_low, pop_high);
300 const ::__m128i sums = ::_mm_sad_epu8(pop8, ::_mm_setzero_si128());
301 return ::_mm_extract_epi16(sums, 0) + ::_mm_extract_epi16(sums, 4);
302#elif defined(NEFORCE_SIMD_SSE2)
303 const auto* raw =
reinterpret_cast<const byte_t*
>(&v);
305 for (
int i = 0; i < 16; ++i) {
307 total += (b & 1) + ((b >> 1) & 1) + ((b >> 2) & 1) + ((b >> 3) & 1) + ((b >> 4) & 1) + ((b >> 5) & 1) +
308 ((b >> 6) & 1) + ((b >> 7) & 1);
311#elif defined(NEFORCE_SIMD_NEON)
312 const ::uint8x16_t low_nibble = ::vandq_u8(v, ::vdupq_n_u8(0x0F));
313 const ::uint8x16_t high_nibble = vshrq_n_u8(v, 4);
314 const ::uint8x16_t lookup = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
315 ::uint8x16_t pop = ::vaddq_u8(::vqtbl1q_u8(lookup, low_nibble), ::vqtbl1q_u8(lookup, high_nibble));
316# ifdef NEFORCE_ARCH_ARM
317 return static_cast<int>(::vaddvq_u8(pop));
320 const auto* bytes =
reinterpret_cast<const byte_t*
>(&pop);
321 for (
int i = 0; i < 16; ++i) {
328 for (
int i = 0; i < 16; ++i) {
330 total += (b & 1) + ((b >> 1) & 1) + ((b >> 2) & 1) + ((b >> 3) & 1) + ((b >> 4) & 1) + ((b >> 5) & 1) +
331 ((b >> 6) & 1) + ((b >> 7) & 1);