// File: /workspace/github_c_makefile_star2_O1/tvlabs[P]edge264/./edge264_residual.c
// Function: add_idct4x4
static noinline void add_idct4x4(Edge264Context *ctx, int iYCbCr, int DCidx, uint8_t *p)
{
	// loading and scaling
	unsigned qP = ctx->t.QP[iYCbCr];
	int sh = qP / 6;
	i8x16 vm = load32(&normAdjust4x4[qP % 6]);
	i8x16 nA = shuffle(vm, (i8x16){0, 2, 0, 2, 2, 1, 2, 1, 0, 2, 0, 2, 2, 1, 2, 1});
	i8x16 wS = ctx->t.pps.weightScale4x4_v[iYCbCr + mb->mbIsInterFlag * 3];
	i16x8 LS0 = mullou8(wS, nA);
	i16x8 LS1 = mulhiu8(wS, nA);
	i32x4 s8 = set32(8); // for SSE
	i32x4 d0 = shlrrs32(ctx->c_v[0] * cvtlo16u32(LS0), sh, 4, s8);
	i32x4 d1 = shlrrs32(ctx->c_v[1] * cvthi16u32(LS0), sh, 4, s8);
	i32x4 d2 = shlrrs32(ctx->c_v[2] * cvtlo16u32(LS1), sh, 4, s8);
	i32x4 d3 = shlrrs32(ctx->c_v[3] * cvthi16u32(LS1), sh, 4, s8);
	ctx->c_v[0] = ctx->c_v[1] = ctx->c_v[2] = ctx->c_v[3] = (i8x16){};
	if (DCidx >= 0)
		d0[0] = ctx->c[16 + DCidx];
	
	// horizontal 1D transform
	i32x4 e0 = d0 + d2;
	i32x4 e1 = d0 - d2;
	i32x4 e2 = (d1 >> 1) - d3;
	i32x4 e3 = (d3 >> 1) + d1;
	i32x4 f0 = e0 + e3;
	i32x4 f1 = e1 + e2;
	i32x4 f2 = e1 - e2;
	i32x4 f3 = e0 - e3;
	
	// matrix transposition
	i32x4 x0 = ziplo32(f0, f1);
	i32x4 x1 = ziplo32(f2, f3);
	i32x4 x2 = ziphi32(f0, f1);
	i32x4 x3 = ziphi32(f2, f3);
	f0 = (i32x4)ziplo64(x0, x1) + 32;
	f1 = ziphi64(x0, x1);
	f2 = ziplo64(x2, x3);
	f3 = ziphi64(x2, x3);
	
	// vertical 1D transform
	i32x4 g0 = f0 + f2;
	i32x4 g1 = f0 - f2;
	i32x4 g2 = (f1 >> 1) - f3;
	i32x4 g3 = (f3 >> 1) + f1;
	i32x4 h0 = g0 + g3;
	i32x4 h1 = g1 + g2;
	i32x4 h2 = g1 - g2;
	i32x4 h3 = g0 - g3;
	
	// final residual values
	i16x8 r0 = shrps32(h0, h1, 6);
	i16x8 r1 = shrps32(h2, h3, 6);
	
	// addition to values in place, clipping and storage
	size_t stride = ctx->t.stride[iYCbCr];
	INIT_P();
	if (ctx->t.samples_clip[iYCbCr][0] == 255) {
		i8x16 p0 = (i32x4){*(int32_t *)P(0, 0), *(int32_t *)P(0, 1)};
		i8x16 p1 = (i32x4){*(int32_t *)P(0, 2), *(int32_t *)P(0, 3)};
		i32x4 u = packus16(addlou8s16(p0, r0), addlou8s16(p1, r1));
		*(int32_t *)P(0, 0) = u[0];
		*(int32_t *)P(0, 1) = u[1];
		*(int32_t *)P(0, 2) = u[2];
		*(int32_t *)P(0, 3) = u[3];
	}
}

// Assembly:
movslq %esi, %rax
movsbl 0x50(%rdi,%rax), %r8d
movl $0xaaaaaaab, %esi       # imm = 0xAAAAAAAB
imulq %r8, %rsi
shrq $0x22, %rsi
leal (%rsi,%rsi), %r9d
leal (%r9,%r9,2), %r9d
subl %r9d, %r8d
leaq 0x23c0a(%rip), %r9      # 0x36b00
vmovd (%r9,%r8,4), %xmm0
vpshufb 0x207cb(%rip), %xmm0, %xmm0 # 0x336d0
movq 0x680(%rdi), %r8
movsbq 0x2(%r8), %r8
leaq (%r8,%r8,2), %r8
addq %rax, %r8
shlq $0x4, %r8
vmovdqa 0x230(%rdi,%r8), %xmm1
vpmovzxbw %xmm1, %xmm2    # xmm2 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero
vpmovzxbw %xmm0, %xmm3    # xmm3 = xmm0[0],zero,xmm0[1],zero,xmm0[2],zero,xmm0[3],zero,xmm0[4],zero,xmm0[5],zero,xmm0[6],zero,xmm0[7],zero
vpmullw %xmm3, %xmm2, %xmm2
vpxor %xmm5, %xmm5, %xmm5
vpunpckhbw %xmm5, %xmm1, %xmm1 # xmm1 = xmm1[8],xmm5[8],xmm1[9],xmm5[9],xmm1[10],xmm5[10],xmm1[11],xmm5[11],xmm1[12],xmm5[12],xmm1[13],xmm5[13],xmm1[14],xmm5[14],xmm1[15],xmm5[15]
vpunpckhbw %xmm5, %xmm0, %xmm0 # xmm0 = xmm0[8],xmm5[8],xmm0[9],xmm5[9],xmm0[10],xmm5[10],xmm0[11],xmm5[11],xmm0[12],xmm5[12],xmm0[13],xmm5[13],xmm0[14],xmm5[14],xmm0[15],xmm5[15]
vpmullw %xmm0, %xmm1, %xmm6
vpmovzxwd %xmm2, %xmm0    # xmm0 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero
vpmulld 0x1b60(%rdi), %xmm0, %xmm1
vmovd %esi, %xmm0
vpslld %xmm0, %xmm1, %xmm1
vpunpckhwd %xmm5, %xmm2, %xmm2 # xmm2 = xmm2[4],xmm5[4],xmm2[5],xmm5[5],xmm2[6],xmm5[6],xmm2[7],xmm5[7]
vpmulld 0x1b70(%rdi), %xmm2, %xmm3
vpbroadcastd 0x242b0(%rip), %xmm2 # 0x37220
vpmovzxwd %xmm6, %xmm4    # xmm4 = xmm6[0],zero,xmm6[1],zero,xmm6[2],zero,xmm6[3],zero
vpmulld 0x1b80(%rdi), %xmm4, %xmm4
vpaddd %xmm2, %xmm1, %xmm1
vpsrad $0x4, %xmm1, %xmm1
vpunpckhwd %xmm5, %xmm6, %xmm5 # xmm5 = xmm6[4],xmm5[4],xmm6[5],xmm5[5],xmm6[6],xmm5[6],xmm6[7],xmm5[7]
vpmulld 0x1b90(%rdi), %xmm5, %xmm5
vpxor %xmm6, %xmm6, %xmm6
vmovdqa %ymm6, 0x1b60(%rdi)
vmovdqa %ymm6, 0x1b80(%rdi)
testl %edx, %edx
js 0x12fbd
leaq 0x1b60(%rdi), %rsi
movl %edx, %edx
vpinsrd $0x0, 0x40(%rsi,%rdx,4), %xmm1, %xmm1
movq %rax, %rdx
shlq $0x4, %rdx
cmpw $0xff, 0x170(%rdi,%rdx)
jne 0x130ed
vpslld %xmm0, %xmm3, %xmm3
vpslld %xmm0, %xmm4, %xmm4
vpslld %xmm0, %xmm5, %xmm0
vpaddd %xmm2, %xmm3, %xmm3
vpaddd %xmm2, %xmm4, %xmm4
vpaddd %xmm2, %xmm0, %xmm0
vpsrad $0x4, %xmm3, %xmm2
vpsrad $0x4, %xmm4, %xmm4
vpsrad $0x4, %xmm0, %xmm5
vpaddd %xmm4, %xmm1, %xmm6
vpsrad $0x5, %xmm0, %xmm0
vpaddd %xmm2, %xmm0, %xmm0
vpaddd %xmm0, %xmm6, %xmm2
vpsubd %xmm4, %xmm1, %xmm1
vpsrad $0x5, %xmm3, %xmm3
vpsubd %xmm5, %xmm3, %xmm3
vpaddd %xmm3, %xmm1, %xmm4
vpunpckldq %xmm4, %xmm2, %xmm5 # xmm5 = xmm2[0],xmm4[0],xmm2[1],xmm4[1]
vpsubd %xmm3, %xmm1, %xmm1
vpsubd %xmm0, %xmm6, %xmm0
vpunpckldq %xmm0, %xmm1, %xmm3 # xmm3 = xmm1[0],xmm0[0],xmm1[1],xmm0[1]
vpunpcklqdq %xmm3, %xmm5, %xmm6 # xmm6 = xmm5[0],xmm3[0]
vpaddd 0x241e9(%rip){1to4}, %xmm6, %xmm6 # 0x37224
vpunpckhdq %xmm4, %xmm2, %xmm2 # xmm2 = xmm2[2],xmm4[2],xmm2[3],xmm4[3]
vpunpckhdq %xmm0, %xmm1, %xmm0 # xmm0 = xmm1[2],xmm0[2],xmm1[3],xmm0[3]
vpunpcklqdq %xmm0, %xmm2, %xmm1 # xmm1 = xmm2[0],xmm0[0]
vpsubd %xmm1, %xmm6, %xmm4
vpunpckhqdq %xmm3, %xmm5, %xmm3 # xmm3 = xmm5[1],xmm3[1]
vpsrad $0x1, %xmm3, %xmm5
vpunpckhqdq %xmm0, %xmm2, %xmm0 # xmm0 = xmm2[1],xmm0[1]
vpsubd %xmm0, %xmm5, %xmm2
vpsubd %xmm2, %xmm4, %xmm5
vpsrad $0x6, %xmm5, %xmm5
vpaddd %xmm1, %xmm6, %xmm1
vpsrad $0x1, %xmm0, %xmm0
vpaddd %xmm3, %xmm0, %xmm0
vpsubd %xmm0, %xmm1, %xmm3
vpsrad $0x6, %xmm3, %xmm3
vpackssdw %xmm3, %xmm5, %xmm3
vpaddd %xmm0, %xmm1, %xmm0
vpsrad $0x6, %xmm0, %xmm0
vpaddd %xmm2, %xmm4, %xmm1
vpsrad $0x6, %xmm1, %xmm1
vpackssdw %xmm1, %xmm0, %xmm0
movzwl 0x34(%rdi,%rax,2), %eax
leaq (%rcx,%rax,8), %rdx
subq %rax, %rdx
vmovd (%rcx), %xmm1
vpinsrd $0x1, (%rcx,%rax), %xmm1, %xmm1
movl %eax, %esi
shll $0x2, %esi
subq %rsi, %rdx
vmovd (%rcx,%rax,2), %xmm2
vpinsrd $0x1, (%rdx), %xmm2, %xmm2
vpmovzxbw %xmm1, %xmm1    # xmm1 = xmm1[0],zero,xmm1[1],zero,xmm1[2],zero,xmm1[3],zero,xmm1[4],zero,xmm1[5],zero,xmm1[6],zero,xmm1[7],zero
vpaddw %xmm1, %xmm0, %xmm0
vpmovzxbw %xmm2, %xmm1    # xmm1 = xmm2[0],zero,xmm2[1],zero,xmm2[2],zero,xmm2[3],zero,xmm2[4],zero,xmm2[5],zero,xmm2[6],zero,xmm2[7],zero
vpaddw %xmm1, %xmm3, %xmm1
vpackuswb %xmm1, %xmm0, %xmm0
vmovd %xmm0, (%rcx)
vpextrd $0x1, %xmm0, (%rcx,%rax)
vpextrd $0x2, %xmm0, (%rcx,%rax,2)
vpextrd $0x3, %xmm0, (%rdx)
vzeroupper
retq