// File: /workspace/github_cpp_makefile_star2_O2/gjoni[P]iPot/src/kdtree.cpp
// Function: kd_nearest_i(kdnode*, double const*, kdnode**, double*, kdhyperrect*)
static void kd_nearest_i(struct kdnode *node, const double *pos, struct kdnode **result, double *result_dist_sq, struct kdhyperrect* rect)
{
	int dir = node->dir;
	int i;
	double dummy, dist_sq;
	struct kdnode *nearer_subtree, *farther_subtree;
	double *nearer_hyperrect_coord, *farther_hyperrect_coord;

	/* Decide whether to go left or right in the tree */
	dummy = pos[dir] - node->pos[dir];
	if (dummy <= 0) {
		nearer_subtree = node->left;
		farther_subtree = node->right;
		nearer_hyperrect_coord = rect->max + dir;
		farther_hyperrect_coord = rect->min + dir;
	} else {
		nearer_subtree = node->right;
		farther_subtree = node->left;
		nearer_hyperrect_coord = rect->min + dir;
		farther_hyperrect_coord = rect->max + dir;
	}

	if (nearer_subtree) {
		/* Slice the hyperrect to get the hyperrect of the nearer subtree */
		dummy = *nearer_hyperrect_coord;
		*nearer_hyperrect_coord = node->pos[dir];
		/* Recurse down into nearer subtree */
		kd_nearest_i(nearer_subtree, pos, result, result_dist_sq, rect);
		/* Undo the slice */
		*nearer_hyperrect_coord = dummy;
	}

	/* Check the distance of the point at the current node, compare it
	 * with our best so far */
	dist_sq = 0;
	for(i=0; i < rect->dim; i++) {
		dist_sq += SQ(node->pos[i] - pos[i]);
	}
	if (dist_sq < *result_dist_sq) {
		*result = node;
		*result_dist_sq = dist_sq;
	}

	if (farther_subtree) {
		/* Get the hyperrect of the farther subtree */
		dummy = *farther_hyperrect_coord;
		*farther_hyperrect_coord = node->pos[dir];
		/* Check if we have to recurse down by calculating the closest
		 * point of the hyperrect and see if it's closer than our
		 * minimum distance in result_dist_sq. */
		if (hyperrect_dist_sq(rect, pos) < *result_dist_sq) {
			/* Recurse down into farther subtree */
			kd_nearest_i(farther_subtree, pos, result, result_dist_sq, rect);
		}
		/* Undo the slice on the hyperrect */
		*farther_hyperrect_coord = dummy;
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r8, %rbx
movq %rsi, %r15
movq %rdi, %rbp
movslq 0x8(%rdi), %r14
movsd (%rsi,%r14,8), %xmm1
movq (%rdi), %rax
movsd (%rax,%r14,8), %xmm0
subsd %xmm0, %xmm1
xorpd %xmm2, %xmm2
xorl %eax, %eax
xorl %esi, %esi
ucomisd %xmm1, %xmm2
setb %al
setae %sil
shll $0x3, %eax
movq 0x8(%rax,%r8), %r12
movq 0x18(%rdi,%rsi,8), %r8
movq 0x18(%rax,%rdi), %rdi
testq %rdi, %rdi
je 0x168e6
xorl %eax, %eax
ucomisd %xmm1, %xmm2
setae %al
movq 0x8(%rbx,%rax,8), %r13
movsd (%r13,%r14,8), %xmm1
movsd %xmm1, 0x10(%rsp)
movsd %xmm0, (%r13,%r14,8)
movq %r15, %rsi
movq %r14, 0x8(%rsp)
movq %rdx, 0x18(%rsp)
movq %r12, 0x20(%rsp)
movq %rcx, %r12
movq %r8, %r14
movq %rbx, %r8
callq 0x16826
xorpd %xmm2, %xmm2
movq %r14, %r8
movq %r12, %rcx
movq 0x20(%rsp), %r12
movq 0x18(%rsp), %rdx
movq 0x8(%rsp), %r14
movsd 0x10(%rsp), %xmm0
movsd %xmm0, (%r13,%r14,8)
movl (%rbx), %eax
xorl %edi, %edi
testl %eax, %eax
cmovlel %edi, %eax
cmpq %rdi, %rax
je 0x16910
movq (%rbp), %rsi
movsd (%rsi,%rdi,8), %xmm0
subsd (%r15,%rdi,8), %xmm0
mulsd %xmm0, %xmm0
addsd %xmm0, %xmm2
incq %rdi
jmp 0x168ef
movsd (%rcx), %xmm0
ucomisd %xmm2, %xmm0
jbe 0x16921
movq %rbp, (%rdx)
movsd %xmm2, (%rcx)
testq %r8, %r8
je 0x169aa
movsd (%r12,%r14,8), %xmm3
movq (%rbp), %rsi
movsd (%rsi,%r14,8), %xmm0
movsd %xmm0, (%r12,%r14,8)
xorpd %xmm0, %xmm0
xorl %edi, %edi
cmpq %rdi, %rax
je 0x16980
movsd (%r15,%rdi,8), %xmm1
movq 0x8(%rbx), %rsi
movsd (%rsi,%rdi,8), %xmm2
ucomisd %xmm1, %xmm2
ja 0x1696f
movq 0x10(%rbx), %rsi
movsd (%rsi,%rdi,8), %xmm2
ucomisd %xmm2, %xmm1
jbe 0x1697b
subsd %xmm1, %xmm2
mulsd %xmm2, %xmm2
addsd %xmm2, %xmm0
incq %rdi
jmp 0x16946
movsd (%rcx), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x169a4
movq %r8, %rdi
movq %r15, %rsi
movq %rbx, %r8
movsd %xmm3, 0x8(%rsp)
callq 0x16826
movsd 0x8(%rsp), %xmm3
movsd %xmm3, (%r12,%r14,8)
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq