// File: /workspace/github_cpp_makefile_star2_O1/6851-2021[P]Cache-Oblivious-Data-Structures/static_search_trees/static_search_trees.cpp
// Function: CA_static_search_tree::update(int, int, int, int, int, int, int, int)
void CA_static_search_tree::update(int tree_l, int num_inner_nodes, int temp_root, int h, int arr_l, int arr_r, int index, int value) {
    if (arr_l == arr_r)
    {
        int last_subtree_size = min((1 << (this->height-((h>>2)<<2))) - 1, 15);
        int real_subtree_root = ((num_inner_nodes<<4)-num_inner_nodes) + (tree_l-num_inner_nodes)*last_subtree_size;
        // printf("update at index %d, real index %d, value %d\n", arr_l, tree_l + temp_root, value);
        this->tree[real_subtree_root + temp_root] = value;
        return;
    }
    int old_tree_l = tree_l, old_temp_root = temp_root;
    int mid = (arr_l + arr_r) >> 1;
    int new_tree_l = 0, new_tree_r = 0;
    if (h > 0 && (h+1) & 3 == 0) {
        h++;
        int old_num_inner_nodes = num_inner_nodes;
        num_inner_nodes += (1 << (h-4));
        // update tree_l
        int mid = (arr_l + arr_r) / 2;
        new_tree_l = (tree_l << 4) + ((temp_root-8) << 1) + 1;
        new_tree_r = (tree_l << 4) + ((temp_root-8) << 1) + 2;
        if (index <= mid) {
            arr_r = mid;
            tree_l = new_tree_l;
        } else {
            arr_l = mid + 1;
            tree_l = new_tree_r;
        }
        temp_root = 1;
        if (h == this->height - 1) {
            int last_subtree_size = min((1 << (this->height-((h>>2)<<2))) - 1, 15);
            int real_subtree_root = ((num_inner_nodes<<4)-num_inner_nodes) + (tree_l-num_inner_nodes)*last_subtree_size;
            this->tree[real_subtree_root + temp_root] = value;
            // printf("here....\n");
            int real_tree_l = ((num_inner_nodes<<4)-num_inner_nodes) + (new_tree_l-num_inner_nodes)*last_subtree_size;
            int real_tree_r = real_tree_l + last_subtree_size;
            int old_real_subtree_root = (old_tree_l<<4) - old_tree_l;
            this->tree[old_real_subtree_root + old_temp_root] = this->merge(this->tree[real_tree_l + 1], this->tree[real_tree_r + 1]);
            return;
        }
    }
    mid = (arr_l + arr_r) >> 1;
    int left_child = temp_root << 1;
    int right_child = (temp_root << 1) + 1;
    h++;
    if (index <= mid)
    {
        this->update(tree_l, num_inner_nodes, left_child, h, arr_l, mid, index, value);
    }
    else
    {
        this->update(tree_l, num_inner_nodes, right_child, h, mid + 1, arr_r, index, value);
    }
    int last_subtree_size = min((1 << (this->height-((h>>2)<<2))) - 1, 15);
    int real_subtree_root = ((num_inner_nodes<<4)-num_inner_nodes) + (tree_l-num_inner_nodes)*last_subtree_size;
    this->tree[real_subtree_root + temp_root] = this->merge(this->tree[real_subtree_root + left_child], this->tree[real_subtree_root + right_child]);
    if (old_tree_l != tree_l) {
        int last_subtree_size = min((1 << (this->height-((h>>2)<<2))) - 1, 15);
        int real_tree_l = ((num_inner_nodes<<4)-num_inner_nodes) + (new_tree_l-num_inner_nodes)*last_subtree_size;
        int real_tree_r = real_tree_l + last_subtree_size;
        int old_real_subtree_root = (old_tree_l << 4) - old_tree_l;
        this->tree[old_real_subtree_root + old_temp_root] = this->merge(this->tree[real_tree_l + 1], this->tree[real_tree_r + 1]);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %r8d, %r14d
movl %ecx, %r8d
movl %edx, %r12d
movl %esi, %ebx
movq %rdi, %r15
movl 0x50(%rsp), %r10d
movl 0x40(%rsp), %r11d
cmpl %r11d, %r9d
jne 0x20ac
movl 0x14(%r15), %ecx
andl $0xfc, %r14d
subl %r14d, %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
shll %cl, %eax
cmpl $-0xf, %eax
movl $0xfffffff0, %ecx       # imm = 0xFFFFFFF0
cmovael %eax, %ecx
notl %ecx
leal (%r12,%r12,4), %eax
leal (%rax,%rax,2), %edx
subl %r12d, %ebx
imull %ecx, %ebx
movq (%r15), %rax
addl %r8d, %edx
addl %edx, %ebx
jmp 0x2163
movl 0x48(%rsp), %ecx
leal (%r11,%r9), %eax
sarl %eax
leal (%r8,%r8), %r13d
movq %r8, (%rsp)
leal 0x1(,%r8,2), %ebp
incl %r14d
cmpl %ecx, %eax
jge 0x20ee
incl %eax
subq $0x8, %rsp
movq %r15, %rdi
movl %ebx, %esi
movl %r12d, %edx
movl %ebp, %ecx
movl %r14d, %r8d
movl %eax, %r9d
pushq %r10
movl 0x58(%rsp), %eax
pushq %rax
pushq %r11
jmp 0x210a
subq $0x8, %rsp
movq %r15, %rdi
movl %ebx, %esi
movl %r12d, %edx
movl %r13d, %ecx
movl %r14d, %r8d
pushq %r10
movl 0x58(%rsp), %r10d
pushq %r10
pushq %rax
callq 0x2048
addq $0x20, %rsp
movl 0x14(%r15), %ecx
andl $0xfc, %r14d
subl %r14d, %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
shll %cl, %eax
cmpl $-0xf, %eax
movl $0xfffffff0, %ecx       # imm = 0xFFFFFFF0
cmovael %eax, %ecx
notl %ecx
leal (%r12,%r12,4), %eax
leal (%rax,%rax,2), %eax
subl %r12d, %ebx
imull %ecx, %ebx
addl %eax, %ebx
movq (%r15), %rax
addl %ebx, %r13d
movslq %r13d, %rcx
movl (%rax,%rcx,4), %ecx
addl %ebx, %ebp
movslq %ebp, %rdx
movl (%rax,%rdx,4), %r10d
cmpl %r10d, %ecx
cmovgl %ecx, %r10d
addl (%rsp), %ebx
movslq %ebx, %rcx
movl %r10d, (%rax,%rcx,4)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop