Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I extract 32 x 4-bit integer from 16 x 8-bit __m128i value

Suppose I have this line of code, which loads 16 x 8-bit unsigned integer using SSE2

// ptr is a pointer to uint8_t array
__m128i b = _mm_load_si128((const __m128i*) ptr);

I would like to split each 8-bit unsigned integer in b (total 16 of them) to 4-bit high and 4-bit low parts. How can I do that?

like image 493
Peter Lee Avatar asked Oct 23 '22 07:10

Peter Lee


1 Answers

You need to mask the lower part and shift the upper part into the right position. Because there is no byte shift SSE instruction, the upper part needs to be masked as well after shifting.

__m128i b =  _mm_load_si128((const __m128i*) ptr);
__m128i mask = _mm_set1_epi8(0xf);
__m128i lower = _mm_and_si128(b, mask);
__m128i upper = _mm_and_si128(_mm_srli_epi16(b, 4), mask);
like image 78
Gunther Piez Avatar answered Oct 31 '22 17:10

Gunther Piez