+#ifdef COULD_HAVE_SSE2
+struct InterleavedBitReaderSSE2 {
+public:
+ InterleavedBitReaderSSE2(const unsigned char *in, unsigned bits)
+ : in(reinterpret_cast<const __m128i *>(in)), bits(bits), mask(_mm_set1_epi32((1U << bits) - 1)) {}
+ __m128i read() {
+ __m128i val = _mm_srli_epi32(_mm_loadu_si128(in), bits_used);
+ if (bits_used + bits > 32) {
+ __m128i val_upper = _mm_slli_epi32(_mm_loadu_si128(in + 1), 32 - bits_used);
+ val = _mm_or_si128(val, val_upper);
+ }
+ val = _mm_and_si128(val, mask);
+
+ bits_used += bits;
+ in += bits_used / 32;
+ bits_used %= 32;
+ return val;
+ }
+
+private:
+ const __m128i *in;
+ const unsigned bits;
+ const __m128i mask;
+ unsigned bits_used = 0;
+};
+#endif
+