static really_inline
u32 packedExtract128(m128 s, const m128 permute, const m128 compare) {
m128 shuffled = pshufb_m128(s, permute);
- print_m128_16x8("shufled", shuffled);
m128 compared = and128(shuffled, compare);
u16 rv = ~movemask128(eq128(compared, shuffled));
return (u32)rv;
static really_inline
m128 pshufb_m128(m128 a, m128 b) {
- return (m128) vec_perm((uint8x16_t)a, (uint8x16_t)a, (uint8x16_t)b);
+ uint8x16_t mask =(uint8x16_t)vec_cmpge((uint8x16_t)b, (uint8x16_t)vec_splats((uint8_t)0x80));
+ uint8x16_t res = vec_perm ((uint8x16_t)a, (uint8x16_t)a, (uint8x16_t)b);
+ return (m128) vec_sel((uint8x16_t)res, (uint8x16_t)zeroes128(), (uint8x16_t)mask);
}
static really_inline
template<>
really_inline SuperVector<16> SuperVector<16>::pshufb<false>(SuperVector<16> b)
{
- return (m128) vec_perm((uint8x16_t)u.v128[0], (uint8x16_t)u.v128[0], (uint8x16_t)b.u.v128[0]);
+ uint8x16_t mask =(uint8x16_t)vec_cmpge((uint8x16_t)b.u.v128[0], (uint8x16_t)vec_splats((uint8_t)0x80));
+ uint8x16_t res = vec_perm ((uint8x16_t)u.v128[0], (uint8x16_t)u.v128[0], (uint8x16_t)b.u.v128[0]);
+ return (m128) vec_sel((uint8x16_t)res, (uint8x16_t)vec_splat_s8(0), (uint8x16_t)mask);
}
template<>
// shuffle a single 1 bit to the front
m128 permute, compare;
build_pshufb_masks_onebit(i, &permute, &compare);
- EXPECT_EQ(1U, packedExtract128(setbit<m128>(i), permute, compare));
+ EXPECT_EQ(1U, packedExtract128(setbit<m128>(i), permute, compare));
EXPECT_EQ(1U, packedExtract128(ones128(), permute, compare));
// we should get zero out of these cases
EXPECT_EQ(0U, packedExtract128(zeroes128(), permute, compare));
}
}
-/*
+
TEST(Shuffle, PackedExtract_templatized_128_1) {
// Try all possible one-bit masks
for (unsigned int i = 0; i < 128; i++) {
}
}
}
-*/
+
#if defined(HAVE_AVX2)
}
u8 vec2[16];
for (int i=0; i<16; i++) {
- vec2[i]=i + (rand() % 16 + 0);
- }
+ vec2[i]=i + (rand() % 15 + 0);
+ }
+
m128 v1 = loadu128(vec);
m128 v2 = loadu128(vec2);
- m128 vres = pshufb_m128(v1, v2);
+ m128 vres = pshufb_m128(v1, v2);
+
u8 res[16];
- store128(res, vres);
+ storeu128(res, vres);
+
for (int i=0; i<16; i++) {
- ASSERT_EQ(vec[vec2[i] % 16 ], res[i]);
+ if(vec2[i] & 0x80){
+ ASSERT_EQ(res[i], 0);
+ }else{
+ ASSERT_EQ(vec[vec2[i] % 16 ], res[i]);
+ }
}
}
auto SP2 = SuperVector<16>::loadu(vec2);
auto SResult = SP1.template pshufb<true>(SP2);
for (int i=0; i<16; i++) {
- ASSERT_EQ(vec[vec2[i] % 16 ],SResult.u.u8[i]);
+ if(vec2[i] & 0x80){
+ ASSERT_EQ(SResult.u.u8[i], 0);
+ }else{
+ ASSERT_EQ(vec[vec2[i] % 16 ],SResult.u.u8[i]);
+ }
}
}