// File: /workspace/github_c_makefile_star2_O1/enzo1982[P]smooth/libraries/libwebp/src/dsp/rescaler_sse2.c
// Function: RescalerImportRowShrink_SSE2
static void RescalerImportRowShrink_SSE2(WebPRescaler* const wrk,
                                         const uint8_t* src) {
  const int x_sub = wrk->x_sub;
  int accum = 0;
  const __m128i zero = _mm_setzero_si128();
  const __m128i mult0 = _mm_set1_epi16(x_sub);
  const __m128i mult1 = _mm_set1_epi32(wrk->fx_scale);
  const __m128i rounder = _mm_set_epi32(0, ROUNDER, 0, ROUNDER);
  __m128i sum = zero;
  rescaler_t* frow = wrk->frow;
  const rescaler_t* const frow_end = wrk->frow + 4 * wrk->dst_width;

  if (wrk->num_channels != 4 || wrk->x_add > (x_sub << 7)) {
    WebPRescalerImportRowShrink_C(wrk, src);
    return;
  }
  assert(!WebPRescalerInputDone(wrk));
  assert(!wrk->x_expand);

  for (; frow < frow_end; frow += 4) {
    __m128i base = zero;
    accum += wrk->x_add;
    while (accum > 0) {
      const __m128i A = _mm_cvtsi32_si128(WebPMemToInt32(src));
      src += 4;
      base = _mm_unpacklo_epi8(A, zero);
      // To avoid overflow, we need: base * x_add / x_sub < 32768
      // => x_add < x_sub << 7. That's a 1/128 reduction ratio limit.
      sum = _mm_add_epi16(sum, base);
      accum -= x_sub;
    }
    {    // Emit next horizontal pixel.
      const __m128i mult = _mm_set1_epi16(-accum);
      const __m128i frac0 = _mm_mullo_epi16(base, mult);  // 16b x 16b -> 32b
      const __m128i frac1 = _mm_mulhi_epu16(base, mult);
      const __m128i frac = _mm_unpacklo_epi16(frac0, frac1);  // frac is 32b
      const __m128i A0 = _mm_mullo_epi16(sum, mult0);
      const __m128i A1 = _mm_mulhi_epu16(sum, mult0);
      const __m128i B0 = _mm_unpacklo_epi16(A0, A1);      // sum * x_sub
      const __m128i frow_out = _mm_sub_epi32(B0, frac);   // sum * x_sub - frac
      const __m128i D0 = _mm_srli_epi64(frac, 32);
      const __m128i D1 = _mm_mul_epu32(frac, mult1);      // 32b x 16b -> 64b
      const __m128i D2 = _mm_mul_epu32(D0, mult1);
      const __m128i E1 = _mm_add_epi64(D1, rounder);
      const __m128i E2 = _mm_add_epi64(D2, rounder);
      const __m128i F1 = _mm_shuffle_epi32(E1, 1 | (3 << 2));
      const __m128i F2 = _mm_shuffle_epi32(E2, 1 | (3 << 2));
      const __m128i G = _mm_unpacklo_epi32(F1, F2);
      sum = _mm_packs_epi32(G, zero);
      _mm_storeu_si128((__m128i*)frow, frow_out);
    }
  }
  assert(accum == 0);
}

// Assembly:
pushq %rax
cmpl $0x4, 0x8(%rdi)
jne 0xe860e
movl 0x28(%rdi), %eax
movl %eax, %ecx
shll $0x7, %ecx
cmpl %ecx, 0x24(%rdi)
jle 0xe8614
popq %rax
jmp 0xdc7af
movl 0x3c(%rdi), %ecx
cmpl 0x30(%rdi), %ecx
jge 0xe870b
cmpl $0x0, (%rdi)
jne 0xe872a
movslq 0x34(%rdi), %rcx
testl %ecx, %ecx
jle 0xe8709
movd %eax, %xmm0
pshuflw $0x0, %xmm0, %xmm0      # xmm0 = xmm0[0,0,0,0,4,5,6,7]
pshufd $0x0, %xmm0, %xmm0      # xmm0 = xmm0[0,0,0,0]
movd 0xc(%rdi), %xmm1
pshufd $0x0, %xmm1, %xmm1      # xmm1 = xmm1[0,0,0,0]
movq 0x60(%rdi), %rdx
shlq $0x4, %rcx
addq %rdx, %rcx
pxor %xmm2, %xmm2
xorl %r8d, %r8d
movdqa 0x45839(%rip), %xmm3    # 0x12dea0
pxor %xmm4, %xmm4
addl 0x24(%rdi), %r8d
jle 0xe868b
movd (%rsi), %xmm5
addq $0x4, %rsi
punpcklbw %xmm2, %xmm5    # xmm5 = xmm5[0],xmm2[0],xmm5[1],xmm2[1],xmm5[2],xmm2[2],xmm5[3],xmm2[3],xmm5[4],xmm2[4],xmm5[5],xmm2[5],xmm5[6],xmm2[6],xmm5[7],xmm2[7]
paddw %xmm5, %xmm4
subl %eax, %r8d
testl %r8d, %r8d
jg 0xe8671
jmp 0xe868f
pxor %xmm5, %xmm5
movl %r8d, %r9d
negl %r9d
movd %r9d, %xmm6
pshuflw $0x0, %xmm6, %xmm6      # xmm6 = xmm6[0,0,0,0,4,5,6,7]
pshufd $0x0, %xmm6, %xmm6      # xmm6 = xmm6[0,0,0,0]
movdqa %xmm6, %xmm7
pmullw %xmm5, %xmm7
pmulhuw %xmm6, %xmm5
punpcklwd %xmm5, %xmm7    # xmm7 = xmm7[0],xmm5[0],xmm7[1],xmm5[1],xmm7[2],xmm5[2],xmm7[3],xmm5[3]
movdqa %xmm4, %xmm5
pmullw %xmm0, %xmm5
pmulhuw %xmm0, %xmm4
punpcklwd %xmm4, %xmm5    # xmm5 = xmm5[0],xmm4[0],xmm5[1],xmm4[1],xmm5[2],xmm4[2],xmm5[3],xmm4[3]
psubd %xmm7, %xmm5
movdqa %xmm7, %xmm6
psrlq $0x20, %xmm6
pmuludq %xmm1, %xmm7
pmuludq %xmm1, %xmm6
paddq %xmm3, %xmm7
paddq %xmm3, %xmm6
pshufd $0xed, %xmm7, %xmm4     # xmm4 = xmm7[1,3,2,3]
pshufd $0xed, %xmm6, %xmm6     # xmm6 = xmm6[1,3,2,3]
punpckldq %xmm6, %xmm4    # xmm4 = xmm4[0],xmm6[0],xmm4[1],xmm6[1]
packssdw %xmm2, %xmm4
movdqu %xmm5, (%rdx)
addq $0x10, %rdx
cmpq %rcx, %rdx
jb 0xe866b
testl %r8d, %r8d
jne 0xe8749
popq %rax
retq
leaq 0x44864(%rip), %rdi     # 0x12cf76
leaq 0x457a7(%rip), %rsi     # 0x12dec0
leaq 0x45800(%rip), %rcx     # 0x12df20
movl $0x80, %edx
callq 0x55710
leaq 0x44945(%rip), %rdi     # 0x12d076
leaq 0x45788(%rip), %rsi     # 0x12dec0
leaq 0x457e1(%rip), %rcx     # 0x12df20
movl $0x81, %edx
callq 0x55710
leaq 0x448d2(%rip), %rdi     # 0x12d022
leaq 0x45769(%rip), %rsi     # 0x12dec0
leaq 0x457c2(%rip), %rcx     # 0x12df20
movl $0xa4, %edx
callq 0x55710