// File: /workspace/github_cpp_makefile_star2_O1/cfiutak1[P]HPyC-KD-Tree/./utils/filewriter/../../src/kdtree/KDTree.hpp
// Function: hpyc::KDTree<float>::buildTree(unsigned long, unsigned long, unsigned int)
void KDTree<ItemT>::buildTree(const std::size_t subarray_begin, const std::size_t subarray_end, const unsigned int depth) {
    std::size_t range = subarray_end - subarray_begin;

    // Base case - If there is one element left, it is already sorted and thus in its correct position.
    if (range == 1) { return; }

    // Base case - If there are two elements left, they will be in their correct positions if they are sorted.
    else if (range == 2) {
        if (this->nodes[depth][subarray_begin] > this->nodes[depth][subarray_begin + 1]) {
            this->swap(subarray_begin, subarray_begin + 1);
        }

        return;
    }

    else if (range == 3) {
        AdaptiveCacheAwareBlockquickselect<ItemT> qs(this->nodes, this->num_dimensions, depth);
        qs.sort3(subarray_begin);

        return;
    }

    // Partition the current subarray around the median at the current dimension.
    AdaptiveCacheAwareBlockquickselect<ItemT> qs(this->nodes, this->num_dimensions, depth);
    qs.nth_element(subarray_begin, subarray_end, (range / 2));

    unsigned int new_depth = (depth + 1) & (-1 + (depth == this->num_dimensions - 1));

    // Build left subtree (all elements left of the median)
    this->buildTree(subarray_begin, subarray_begin + (range / 2), new_depth);

    // Build right subtree (all elements right of the median)
    this->buildTree(subarray_begin + (range / 2) + 1, subarray_end, new_depth);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdx, %r12
subq %rsi, %r12
cmpq $0x1, %r12
je 0x3541
movl %ecx, %ebp
movq %rsi, %rbx
movq %rdi, %r14
cmpq $0x3, %r12
je 0x340c
cmpq $0x2, %r12
jne 0x34df
movq 0x8(%r14), %rax
movl %ebp, %ecx
movq (%rax,%rcx,8), %rcx
movss (%rcx,%rbx,4), %xmm0
ucomiss 0x4(%rcx,%rbx,4), %xmm0
jbe 0x3541
movq 0x18(%r14), %rcx
testq %rcx, %rcx
je 0x3541
xorl %edx, %edx
movq (%rax,%rdx,8), %rsi
movss (%rsi,%rbx,4), %xmm0
movss 0x4(%rsi,%rbx,4), %xmm1
movss %xmm1, (%rsi,%rbx,4)
movss %xmm0, 0x4(%rsi,%rbx,4)
incq %rdx
cmpq %rdx, %rcx
jne 0x33e5
jmp 0x3541
movq 0x8(%r14), %rax
movl %ebp, %ecx
movq (%rax,%rcx,8), %rdx
movss 0x4(%rdx,%rbx,4), %xmm0
ucomiss 0x8(%rdx,%rbx,4), %xmm0
setbe %sil
movq 0x18(%r14), %rcx
testq %rcx, %rcx
sete %dil
orb %sil, %dil
jne 0x345b
xorl %esi, %esi
movq (%rax,%rsi,8), %rdi
movss 0x4(%rdi,%rbx,4), %xmm0
movss 0x8(%rdi,%rbx,4), %xmm1
movss %xmm1, 0x4(%rdi,%rbx,4)
movss %xmm0, 0x8(%rdi,%rbx,4)
incq %rsi
cmpq %rsi, %rcx
jne 0x3437
movss (%rdx,%rbx,4), %xmm0
ucomiss 0x4(%rdx,%rbx,4), %xmm0
setbe %sil
testq %rcx, %rcx
sete %dil
orb %sil, %dil
jne 0x3499
xorl %esi, %esi
movq (%rax,%rsi,8), %rdi
movss (%rdi,%rbx,4), %xmm0
movss 0x4(%rdi,%rbx,4), %xmm1
movss %xmm1, (%rdi,%rbx,4)
movss %xmm0, 0x4(%rdi,%rbx,4)
incq %rsi
cmpq %rsi, %rcx
jne 0x3477
movss 0x4(%rdx,%rbx,4), %xmm0
ucomiss 0x8(%rdx,%rbx,4), %xmm0
setbe %dl
testq %rcx, %rcx
sete %sil
orb %dl, %sil
jne 0x3541
xorl %edx, %edx
movq (%rax,%rdx,8), %rsi
movss 0x4(%rsi,%rbx,4), %xmm0
movss 0x8(%rsi,%rbx,4), %xmm1
movss %xmm1, 0x4(%rsi,%rbx,4)
movss %xmm0, 0x8(%rsi,%rbx,4)
incq %rdx
cmpq %rdx, %rcx
jne 0x34b9
jmp 0x3541
movq %rdx, %r15
movq 0x8(%r14), %rax
movq 0x18(%r14), %rcx
movq %rsp, %rdi
movq %rax, (%rdi)
movq %rcx, 0x8(%rdi)
movl %ebp, 0x10(%rdi)
shrq %r12
movq %rbx, %rsi
movq %r12, %rcx
callq 0x3550
movl %ebp, %eax
incl %ebp
movq 0x18(%r14), %rcx
decq %rcx
xorl %r13d, %r13d
cmpq %rax, %rcx
cmovnel %ebp, %r13d
leaq (%r12,%rbx), %rdx
movq %r14, %rdi
movq %rbx, %rsi
movl %r13d, %ecx
callq 0x3386
leaq (%r12,%rbx), %rsi
incq %rsi
movq %r14, %rdi
movq %r15, %rdx
movl %r13d, %ecx
callq 0x3386
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq