title: _mm_alignr_epi8 (PALIGNR) equivalent in AVX2
body: <p>In SSE3, the PALIGNR instruction performs the following: </p>
  
  <blockquote>
    <p>PALIGNR concatenates the destination operand (the first operand) and the source operand (the second operand) into an intermediate composite, shifts the composite at byte granularity to the right by a constant immediate, and extracts the right-aligned result into the destination. </p>
  </blockquote>
  
  <p>I'm currently in the midst of porting my SSE4 code to use AVX2 instructions and working on 256bit registers instead of 128bit.
  Naively, I believed that the intrinsics function <code>_mm256_alignr_epi8</code> (VPALIGNR) performs the same operation as <code>_mm_alignr_epi8</code> only on 256bit registers. Sadly however, that is not exactly the case. In fact, <code>_mm256_alignr_epi8</code> treats the 256bit register as 2 128bit registers and performs 2 "align" operations on the two neighboring 128bit registers. Effectively performing the same operation as <code>_mm_alignr_epi8</code> but on 2 registers at once. It's most clearly illustrated here: <a href="http://www2.fz-juelich.de/jsc/docs/vendordocs/cce/doc/main_cls/intref_cls/common/intref_avx2_alignr.htm" rel="noreferrer">_mm256_alignr_epi8</a></p>
  
  <p>Currently my solution is to keep using <code>_mm_alignr_epi8</code> by splitting the ymm (256bit) registers into two xmm (128bit) registers (high and low), like so:</p>
  
  <pre><code>__m128i xmm_ymm1_hi = _mm256_extractf128_si256(ymm1, 0);
  __m128i xmm_ymm1_lo = _mm256_extractf128_si256(ymm1, 1);
  __m128i xmm_ymm2_hi = _mm256_extractf128_si256(ymm2, 0);
  __m128i xmm_ymm_aligned_lo = _mm_alignr_epi8(xmm_ymm1_lo, xmm_ymm1_hi, 1);
  __m128i xmm_ymm_aligned_hi = _mm_alignr_epi8(xmm_ymm2_hi, xmm_ymm1_lo, 1);
  __m256i xmm_ymm_aligned = _mm256_set_m128i(xmm_ymm_aligned_lo, xmm_ymm_aligned_hi);
  </code></pre>
  
  <p>This works, but there has to be a better way, right?
  Is there a perhaps more "general" AVX2 instruction that should be using to get the same result?</p>