// File: /workspace/github_c_makefile_star2_O2/enzo1982[P]smooth/libraries/libwebp/src/dsp/alpha_processing_sse2.c
// Function: DispatchAlpha_SSE2
static int DispatchAlpha_SSE2(const uint8_t* WEBP_RESTRICT alpha,
                              int alpha_stride, int width, int height,
                              uint8_t* WEBP_RESTRICT dst, int dst_stride) {
  // alpha_and stores an 'and' operation of all the alpha[] values. The final
  // value is not 0xff if any of the alpha[] is not equal to 0xff.
  uint32_t alpha_and = 0xff;
  int i, j;
  const __m128i zero = _mm_setzero_si128();
  const __m128i rgb_mask = _mm_set1_epi32((int)0xffffff00);  // to preserve RGB
  const __m128i all_0xff = _mm_set_epi32(0, 0, ~0, ~0);
  __m128i all_alphas = all_0xff;

  // We must be able to access 3 extra bytes after the last written byte
  // 'dst[4 * width - 4]', because we don't know if alpha is the first or the
  // last byte of the quadruplet.
  const int limit = (width - 1) & ~7;

  for (j = 0; j < height; ++j) {
    __m128i* out = (__m128i*)dst;
    for (i = 0; i < limit; i += 8) {
      // load 8 alpha bytes
      const __m128i a0 = _mm_loadl_epi64((const __m128i*)&alpha[i]);
      const __m128i a1 = _mm_unpacklo_epi8(a0, zero);
      const __m128i a2_lo = _mm_unpacklo_epi16(a1, zero);
      const __m128i a2_hi = _mm_unpackhi_epi16(a1, zero);
      // load 8 dst pixels (32 bytes)
      const __m128i b0_lo = _mm_loadu_si128(out + 0);
      const __m128i b0_hi = _mm_loadu_si128(out + 1);
      // mask dst alpha values
      const __m128i b1_lo = _mm_and_si128(b0_lo, rgb_mask);
      const __m128i b1_hi = _mm_and_si128(b0_hi, rgb_mask);
      // combine
      const __m128i b2_lo = _mm_or_si128(b1_lo, a2_lo);
      const __m128i b2_hi = _mm_or_si128(b1_hi, a2_hi);
      // store
      _mm_storeu_si128(out + 0, b2_lo);
      _mm_storeu_si128(out + 1, b2_hi);
      // accumulate eight alpha 'and' in parallel
      all_alphas = _mm_and_si128(all_alphas, a0);
      out += 2;
    }
    for (; i < width; ++i) {
      const uint32_t alpha_value = alpha[i];
      dst[4 * i] = alpha_value;
      alpha_and &= alpha_value;
    }
    alpha += alpha_stride;
    dst += dst_stride;
  }
  // Combine the eight alpha 'and' into a 8-bit mask.
  alpha_and &= _mm_movemask_epi8(_mm_cmpeq_epi8(all_alphas, all_0xff));
  return (alpha_and != 0xff);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
leal -0x1(%rdx), %r10d
andl $-0x8, %r10d
movslq %esi, %rax
movslq %r9d, %rsi
movslq %r10d, %r9
movslq %edx, %r10
xorl %r11d, %r11d
testl %ecx, %ecx
cmovlel %r11d, %ecx
movl $0xff, %edx
movq 0x4639d(%rip), %xmm0    # 0x11c990
pxor %xmm1, %xmm1
movdqa 0x46331(%rip), %xmm2    # 0x11c930
cmpl %ecx, %r11d
je 0xd668d
movq %rdi, %rbx
movq %r8, %r14
xorl %r15d, %r15d
cmpq %r9, %r15
jge 0xd667a
movq (%rdi,%r15), %xmm3
pand %xmm3, %xmm0
punpcklbw %xmm1, %xmm3    # xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1],xmm3[2],xmm1[2],xmm3[3],xmm1[3],xmm3[4],xmm1[4],xmm3[5],xmm1[5],xmm3[6],xmm1[6],xmm3[7],xmm1[7]
movdqa %xmm3, %xmm4
punpcklwd %xmm1, %xmm4    # xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1],xmm4[2],xmm1[2],xmm4[3],xmm1[3]
punpckhwd %xmm1, %xmm3    # xmm3 = xmm3[4],xmm1[4],xmm3[5],xmm1[5],xmm3[6],xmm1[6],xmm3[7],xmm1[7]
movdqu (%r8,%r15,4), %xmm5
movdqu 0x10(%r8,%r15,4), %xmm6
pand %xmm2, %xmm5
por %xmm4, %xmm5
pand %xmm2, %xmm6
por %xmm3, %xmm6
movdqu %xmm5, (%r8,%r15,4)
movdqu %xmm6, 0x10(%r8,%r15,4)
addq $0x8, %r15
addq $0x20, %r14
addq $0x8, %rbx
jmp 0xd6611
movzbl (%rbx), %ebp
movb %bpl, (%r14)
andl %ebp, %edx
incq %r15
addq $0x4, %r14
incq %rbx
cmpq %r10, %r15
jl 0xd6668
addq %rax, %rdi
addq %rsi, %r8
incl %r11d
jmp 0xd65ff
pcmpeqb 0x105ab(%rip), %xmm0    # 0xe6c40
pmovmskb %xmm0, %eax
andl %eax, %edx
xorl %eax, %eax
cmpl $0xff, %edx
setne %al
popq %rbx
popq %r14
popq %r15
popq %rbp
retq