// File: /workspace/github_c_makefile_star2_O3/DavidSM64[P]n64graphics_ci/exoquant/exoquant.c
// Function: exq_sum_node
void exq_sum_node(exq_node *pNode)
{
	int n, n2;
	exq_color fsum, fsum2, vc, tmp, tmp2, sum, sum2;
	exq_histogram *pCur;
	exq_float isqrt, nv, v;

	n = 0;
	fsum.r = fsum.g = fsum.b = fsum.a = 0;
	fsum2.r = fsum2.g = fsum2.b = fsum2.a = 0;

	for(pCur = pNode->pHistogram; pCur != NULL; pCur = pCur->pNext)
	{
		n += pCur->num;
		fsum.r += pCur->color.r * pCur->num;
		fsum.g += pCur->color.g * pCur->num;
		fsum.b += pCur->color.b * pCur->num;
		fsum.a += pCur->color.a * pCur->num;
		fsum2.r += pCur->color.r * pCur->color.r * pCur->num;
		fsum2.g += pCur->color.g * pCur->color.g * pCur->num;
		fsum2.b += pCur->color.b * pCur->color.b * pCur->num;
		fsum2.a += pCur->color.a * pCur->color.a * pCur->num;
	}
	pNode->num = n;
	if(n == 0)
	{
		pNode->vdif = 0;
		pNode->err = 0;
		return;
	}

	pNode->avg.r = fsum.r / n;
	pNode->avg.g = fsum.g / n;
	pNode->avg.b = fsum.b / n;
	pNode->avg.a = fsum.a / n;

	vc.r = fsum2.r - fsum.r * pNode->avg.r;
	vc.g = fsum2.g - fsum.g * pNode->avg.g;
	vc.b = fsum2.b - fsum.b * pNode->avg.b;
	vc.a = fsum2.a - fsum.a * pNode->avg.a;

	v = vc.r + vc.g + vc.b + vc.a;
	pNode->err = v;
	pNode->vdif = -v;

	if(vc.r > vc.g && vc.r > vc.b && vc.r > vc.a)
		exq_sort(&pNode->pHistogram, exq_sort_by_r);
	else if(vc.g > vc.b && vc.g > vc.a)
		exq_sort(&pNode->pHistogram, exq_sort_by_g);
	else if(vc.b > vc.a)
		exq_sort(&pNode->pHistogram, exq_sort_by_b);
	else
		exq_sort(&pNode->pHistogram, exq_sort_by_a);

	pNode->dir.r = pNode->dir.g = pNode->dir.b = pNode->dir.a = 0;
	for(pCur = pNode->pHistogram; pCur != NULL; pCur = pCur->pNext)
	{
		tmp.r = (pCur->color.r - pNode->avg.r) * pCur->num;
		tmp.g = (pCur->color.g - pNode->avg.g) * pCur->num;
		tmp.b = (pCur->color.b - pNode->avg.b) * pCur->num;
		tmp.a = (pCur->color.a - pNode->avg.a) * pCur->num;
		if(tmp.r * pNode->dir.r + tmp.g * pNode->dir.g +
			tmp.b * pNode->dir.b + tmp.a * pNode->dir.a < 0)
		{
			tmp.r = -tmp.r;
			tmp.g = -tmp.g;
			tmp.b = -tmp.b;
			tmp.a = -tmp.a;
		}
		pNode->dir.r += tmp.r;
		pNode->dir.g += tmp.g;
		pNode->dir.b += tmp.b;
		pNode->dir.a += tmp.a;
	}
	isqrt = 1 / sqrt(pNode->dir.r * pNode->dir.r +
		pNode->dir.g * pNode->dir.g + pNode->dir.b * pNode->dir.b +
		pNode->dir.a * pNode->dir.a);
	pNode->dir.r *= isqrt;
	pNode->dir.g *= isqrt;
	pNode->dir.b *= isqrt;
	pNode->dir.a *= isqrt;

	exq_sort_dir = pNode->dir;
	exq_sort(&pNode->pHistogram, exq_sort_by_dir);

	sum.r = sum.g = sum.b = sum.a = 0;
	sum2.r = sum2.g = sum2.b = sum2.a = 0;
	n2 = 0;
	pNode->pSplit = pNode->pHistogram;
	for(pCur = pNode->pHistogram; pCur != NULL; pCur = pCur->pNext)
	{
		if(pNode->pSplit == NULL)
			pNode->pSplit = pCur;

		n2 += pCur->num;
		sum.r += pCur->color.r * pCur->num;
		sum.g += pCur->color.g * pCur->num;
		sum.b += pCur->color.b * pCur->num;
		sum.a += pCur->color.a * pCur->num;
		sum2.r += pCur->color.r * pCur->color.r * pCur->num;
		sum2.g += pCur->color.g * pCur->color.g * pCur->num;
		sum2.b += pCur->color.b * pCur->color.b * pCur->num;
		sum2.a += pCur->color.a * pCur->color.a * pCur->num;

		if(n == n2)
			break;

		tmp.r = sum2.r - sum.r*sum.r / n2;
		tmp.g = sum2.g - sum.g*sum.g / n2;
		tmp.b = sum2.b - sum.b*sum.b / n2;
		tmp.a = sum2.a - sum.a*sum.a / n2;
		tmp2.r = (fsum2.r - sum2.r) - (fsum.r-sum.r)*(fsum.r-sum.r) / (n - n2);
		tmp2.g = (fsum2.g - sum2.g) - (fsum.g-sum.g)*(fsum.g-sum.g) / (n - n2);
		tmp2.b = (fsum2.b - sum2.b) - (fsum.b-sum.b)*(fsum.b-sum.b) / (n - n2);
		tmp2.a = (fsum2.a - sum2.a) - (fsum.a-sum.a)*(fsum.a-sum.a) / (n - n2);

		nv = tmp.r + tmp.g + tmp.b + tmp.a + tmp2.r + tmp2.g + tmp2.b + tmp2.a;
		if(-nv > pNode->vdif)
		{
			pNode->vdif = -nv;
			pNode->pSplit = NULL;
		}
	}

	if(pNode->pSplit == pNode->pHistogram)
		pNode->pSplit = pNode->pSplit->pNext;

	pNode->vdif += v;
//	printf("error sum: %f, vdif: %f\n", pNode->err, pNode->vdif);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x58, %rsp
movq %rdi, %rbx
movq 0x58(%rdi), %rax
testq %rax, %rax
je 0x1ace
leaq 0x58(%rbx), %r14
xorpd %xmm6, %xmm6
xorl %r15d, %r15d
xorpd %xmm7, %xmm7
xorpd %xmm8, %xmm8
xorpd %xmm9, %xmm9
xorpd %xmm10, %xmm10
xorpd %xmm11, %xmm11
xorpd %xmm12, %xmm12
xorpd %xmm13, %xmm13
movl 0x58(%rax), %ecx
addl %ecx, %r15d
xorps %xmm0, %xmm0
cvtsi2sd %ecx, %xmm0
movsd (%rax), %xmm1
movsd 0x8(%rax), %xmm2
movapd %xmm1, %xmm3
mulsd %xmm0, %xmm3
addsd %xmm3, %xmm9
movapd %xmm2, %xmm3
mulsd %xmm0, %xmm3
addsd %xmm3, %xmm8
movsd 0x10(%rax), %xmm3
movapd %xmm3, %xmm4
mulsd %xmm0, %xmm4
addsd %xmm4, %xmm7
movsd 0x18(%rax), %xmm4
movapd %xmm4, %xmm5
mulsd %xmm0, %xmm5
addsd %xmm5, %xmm6
mulsd %xmm1, %xmm1
mulsd %xmm0, %xmm1
addsd %xmm1, %xmm13
mulsd %xmm2, %xmm2
mulsd %xmm0, %xmm2
addsd %xmm2, %xmm12
mulsd %xmm3, %xmm3
mulsd %xmm0, %xmm3
addsd %xmm3, %xmm11
mulsd %xmm4, %xmm4
mulsd %xmm0, %xmm4
addsd %xmm4, %xmm10
movq 0x60(%rax), %rax
testq %rax, %rax
jne 0x1946
movl %r15d, 0x50(%rbx)
testl %r15d, %r15d
je 0x1ad5
xorps %xmm0, %xmm0
cvtsi2sd %r15d, %xmm0
movapd %xmm9, %xmm1
divsd %xmm0, %xmm1
movsd %xmm1, 0x20(%rbx)
movapd %xmm8, %xmm3
divsd %xmm0, %xmm3
movsd %xmm3, 0x28(%rbx)
movapd %xmm7, %xmm4
divsd %xmm0, %xmm4
movsd %xmm4, 0x30(%rbx)
movapd %xmm6, %xmm5
divsd %xmm0, %xmm5
movsd %xmm5, 0x38(%rbx)
mulsd %xmm9, %xmm1
movapd %xmm13, %xmm2
subsd %xmm1, %xmm2
mulsd %xmm8, %xmm3
movapd %xmm12, %xmm0
subsd %xmm3, %xmm0
mulsd %xmm7, %xmm4
movapd %xmm11, %xmm1
subsd %xmm4, %xmm1
mulsd %xmm6, %xmm5
movapd %xmm10, %xmm3
subsd %xmm5, %xmm3
movapd %xmm2, %xmm5
addsd %xmm0, %xmm5
addsd %xmm1, %xmm5
addsd %xmm3, %xmm5
movsd %xmm5, 0x48(%rbx)
movapd 0x105b9(%rip), %xmm4    # 0x12030
xorpd %xmm5, %xmm4
movlpd %xmm4, 0x40(%rbx)
ucomisd %xmm0, %xmm2
movsd %xmm6, -0x20(%rbp)
movsd %xmm7, -0x58(%rbp)
movsd %xmm8, -0x50(%rbp)
movsd %xmm9, -0x48(%rbp)
movsd %xmm10, -0x40(%rbp)
movsd %xmm11, -0x38(%rbp)
movsd %xmm12, -0x30(%rbp)
movsd %xmm13, -0x28(%rbp)
movapd %xmm5, -0x70(%rbp)
jbe 0x1ae3
ucomisd %xmm1, %xmm2
jbe 0x1ae3
ucomisd %xmm3, %xmm2
jbe 0x1ae3
leaq 0x8ca(%rip), %rsi       # 0x2396
jmp 0x1b0e
movl $0x0, 0x50(%rbx)
xorpd %xmm0, %xmm0
movupd %xmm0, 0x40(%rbx)
jmp 0x1f2c
ucomisd %xmm1, %xmm0
jbe 0x1af8
ucomisd %xmm3, %xmm0
jbe 0x1af8
leaq 0x8aa(%rip), %rsi       # 0x23a0
jmp 0x1b0e
ucomisd %xmm3, %xmm1
leaq 0x8a8(%rip), %rax       # 0x23ab
leaq 0x8ac(%rip), %rsi       # 0x23b6
cmovaq %rax, %rsi
movq %r14, %rdi
callq 0x2280
xorpd %xmm0, %xmm0
movupd %xmm0, 0x10(%rbx)
movupd %xmm0, (%rbx)
movq 0x58(%rbx), %rax
testq %rax, %rax
je 0x1c20
movsd 0x20(%rbx), %xmm4
movsd 0x28(%rbx), %xmm5
movsd 0x30(%rbx), %xmm6
movsd 0x38(%rbx), %xmm7
xorpd %xmm8, %xmm8
movapd 0x104de(%rip), %xmm9    # 0x12030
xorpd %xmm0, %xmm0
xorpd %xmm1, %xmm1
xorpd %xmm2, %xmm2
xorpd %xmm3, %xmm3
movsd (%rax), %xmm10
subsd %xmm4, %xmm10
movsd 0x8(%rax), %xmm11
subsd %xmm5, %xmm11
xorps %xmm14, %xmm14
cvtsi2sdl 0x58(%rax), %xmm14
mulsd %xmm14, %xmm10
mulsd %xmm14, %xmm11
movsd 0x10(%rax), %xmm12
subsd %xmm6, %xmm12
mulsd %xmm14, %xmm12
movsd 0x18(%rax), %xmm13
subsd %xmm7, %xmm13
mulsd %xmm14, %xmm13
movapd %xmm11, %xmm14
mulsd %xmm2, %xmm14
movapd %xmm10, %xmm15
mulsd %xmm3, %xmm15
addsd %xmm14, %xmm15
movapd %xmm12, %xmm14
mulsd %xmm1, %xmm14
addsd %xmm15, %xmm14
movapd %xmm13, %xmm15
mulsd %xmm0, %xmm15
addsd %xmm14, %xmm15
ucomisd %xmm15, %xmm8
jbe 0x1bfd
xorpd %xmm9, %xmm10
xorpd %xmm9, %xmm11
xorpd %xmm9, %xmm12
xorpd %xmm9, %xmm13
addsd %xmm10, %xmm3
addsd %xmm11, %xmm2
addsd %xmm12, %xmm1
addsd %xmm13, %xmm0
movq 0x60(%rax), %rax
testq %rax, %rax
jne 0x1b62
jmp 0x1c30
xorpd %xmm0, %xmm0
xorpd %xmm1, %xmm1
xorpd %xmm2, %xmm2
xorpd %xmm3, %xmm3
movapd %xmm2, %xmm4
mulsd %xmm2, %xmm4
movapd %xmm3, %xmm5
mulsd %xmm3, %xmm5
addsd %xmm4, %xmm5
movapd %xmm1, %xmm4
mulsd %xmm1, %xmm4
addsd %xmm5, %xmm4
movapd %xmm0, %xmm5
mulsd %xmm0, %xmm5
addsd %xmm4, %xmm5
xorps %xmm4, %xmm4
sqrtsd %xmm5, %xmm4
movsd 0x103e5(%rip), %xmm5    # 0x12050
divsd %xmm4, %xmm5
mulsd %xmm5, %xmm3
movsd %xmm3, (%rbx)
mulsd %xmm5, %xmm2
movsd %xmm2, 0x8(%rbx)
mulsd %xmm5, %xmm1
movsd %xmm1, 0x10(%rbx)
mulsd %xmm0, %xmm5
movsd %xmm5, 0x18(%rbx)
movups (%rbx), %xmm0
movups %xmm0, 0x1750c(%rip)    # 0x191a8
movupd 0x10(%rbx), %xmm0
movupd %xmm0, 0x1750f(%rip)    # 0x191b8
leaq 0x711(%rip), %rsi       # 0x23c1
movq %r14, %rdi
callq 0x2280
movq 0x58(%rbx), %rax
movq %rax, 0x60(%rbx)
xorl %ecx, %ecx
testq %rax, %rax
je 0x1f0e
xorpd %xmm0, %xmm0
movapd 0x10359(%rip), %xmm1    # 0x12030
movq %rax, %rdx
movq %rax, %rsi
xorpd %xmm2, %xmm2
xorpd %xmm3, %xmm3
xorpd %xmm4, %xmm4
xorpd %xmm5, %xmm5
xorpd %xmm6, %xmm6
xorpd %xmm7, %xmm7
xorpd %xmm8, %xmm8
movsd -0x20(%rbp), %xmm15
testq %rdx, %rdx
jne 0x1d0c
movq %rsi, 0x60(%rbx)
movq %rsi, %rdx
movl 0x58(%rsi), %r8d
addl %r8d, %ecx
movl %r15d, %edi
subl %ecx, %edi
je 0x1f10
xorps %xmm9, %xmm9
cvtsi2sd %r8d, %xmm9
movsd (%rsi), %xmm10
movsd 0x8(%rsi), %xmm11
movapd %xmm10, %xmm12
mulsd %xmm9, %xmm12
addsd %xmm12, %xmm5
movapd %xmm11, %xmm12
mulsd %xmm9, %xmm12
addsd %xmm12, %xmm6
movsd 0x10(%rsi), %xmm12
movapd %xmm12, %xmm13
mulsd %xmm9, %xmm13
addsd %xmm13, %xmm7
movsd 0x18(%rsi), %xmm13
movapd %xmm13, %xmm14
mulsd %xmm9, %xmm14
addsd %xmm14, %xmm8
mulsd %xmm10, %xmm10
mulsd %xmm9, %xmm10
addsd %xmm10, %xmm0
mulsd %xmm11, %xmm11
mulsd %xmm9, %xmm11
addsd %xmm11, %xmm2
mulsd %xmm12, %xmm12
mulsd %xmm9, %xmm12
addsd %xmm12, %xmm3
mulsd %xmm13, %xmm13
mulsd %xmm9, %xmm13
addsd %xmm13, %xmm4
movapd %xmm5, %xmm9
xorps %xmm10, %xmm10
cvtsi2sd %ecx, %xmm10
mulsd %xmm5, %xmm9
divsd %xmm10, %xmm9
movapd %xmm0, %xmm11
subsd %xmm9, %xmm11
movapd %xmm6, %xmm9
mulsd %xmm6, %xmm9
divsd %xmm10, %xmm9
movapd %xmm2, %xmm12
subsd %xmm9, %xmm12
addsd %xmm11, %xmm12
movapd %xmm7, %xmm9
mulsd %xmm7, %xmm9
divsd %xmm10, %xmm9
movapd %xmm3, %xmm11
subsd %xmm9, %xmm11
addsd %xmm12, %xmm11
movapd %xmm8, %xmm9
mulsd %xmm8, %xmm9
divsd %xmm10, %xmm9
movapd %xmm4, %xmm10
subsd %xmm9, %xmm10
addsd %xmm11, %xmm10
movsd -0x28(%rbp), %xmm11
subsd %xmm0, %xmm11
movsd -0x48(%rbp), %xmm12
subsd %xmm5, %xmm12
xorps %xmm9, %xmm9
cvtsi2sd %edi, %xmm9
mulsd %xmm12, %xmm12
divsd %xmm9, %xmm12
subsd %xmm12, %xmm11
addsd %xmm10, %xmm11
movsd -0x30(%rbp), %xmm10
subsd %xmm2, %xmm10
movsd -0x50(%rbp), %xmm12
subsd %xmm6, %xmm12
mulsd %xmm12, %xmm12
divsd %xmm9, %xmm12
subsd %xmm12, %xmm10
addsd %xmm11, %xmm10
movsd -0x38(%rbp), %xmm11
subsd %xmm3, %xmm11
movsd -0x58(%rbp), %xmm12
subsd %xmm7, %xmm12
mulsd %xmm12, %xmm12
divsd %xmm9, %xmm12
subsd %xmm12, %xmm11
addsd %xmm10, %xmm11
movapd %xmm15, %xmm10
subsd %xmm8, %xmm10
mulsd %xmm10, %xmm10
divsd %xmm9, %xmm10
movsd -0x40(%rbp), %xmm9
subsd %xmm4, %xmm9
subsd %xmm10, %xmm9
addsd %xmm11, %xmm9
xorpd %xmm1, %xmm9
ucomisd 0x40(%rbx), %xmm9
jbe 0x1eff
movsd %xmm9, 0x40(%rbx)
movq $0x0, 0x60(%rbx)
xorl %edx, %edx
movq 0x60(%rsi), %rsi
testq %rsi, %rsi
jne 0x1d00
jmp 0x1f10
xorl %edx, %edx
cmpq %rax, %rdx
jne 0x1f1d
movq 0x60(%rdx), %rax
movq %rax, 0x60(%rbx)
movapd -0x70(%rbp), %xmm0
addsd 0x40(%rbx), %xmm0
movsd %xmm0, 0x40(%rbx)
addq $0x58, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq