// File: /workspace/github_cpp_makefile_star2_O3/6851-2021[P]Cache-Oblivious-Data-Structures/static_search_trees/static_search_trees.cpp
// Function: co_static_search_tree::range_update(int, int, int, int, int, int, int*)
void co_static_search_tree::range_update(int block_index, int height, int range_left,  int og_height, int query_range_left, int query_range_right, int* items) {
    if (height == 1)
    {

        this->tree[block_index] = items[range_left];
        return;
    }

    //update bottom tree
    int bottom_tree_height = bottom_tree_height_memo[height];

    int top_tree_height = height - bottom_tree_height;
    
    int top_tree_size = (1 << top_tree_height) - 1;

    int bottom_tree_og_height = og_height - top_tree_height;
    int bottom_tree_size = (1 << bottom_tree_height) - 1;

    int bottom_tree_index_range_left = (query_range_left - range_left) >> (bottom_tree_og_height - 1);
    int bottom_tree_index_range_right = (query_range_right - range_left) >> (bottom_tree_og_height - 1);

    for (int bottom_tree_index = bottom_tree_index_range_left; bottom_tree_index <= bottom_tree_index_range_right; ++bottom_tree_index) {
        int bottom_tree_block_index = block_index + top_tree_size + (bottom_tree_index << bottom_tree_height) - bottom_tree_index;
        int bottom_tree_range_left = range_left + (bottom_tree_index << (bottom_tree_og_height - 1));
        this->range_update(bottom_tree_block_index, bottom_tree_height, bottom_tree_range_left, bottom_tree_og_height, max(query_range_left, bottom_tree_range_left), min(query_range_right, bottom_tree_range_left + (1 << (bottom_tree_og_height - 1)) - 1), items);
    }

    bottom_tree_index_range_left = bottom_tree_index_range_left & (~1);
    int range_lenght = (1 << (bottom_tree_og_height - 1));
    for (int bottom_tree_index = bottom_tree_index_range_left; bottom_tree_index <= bottom_tree_index_range_right; bottom_tree_index += 2)
    {
        int bottom_tree_block_index = block_index + top_tree_size + (bottom_tree_index << bottom_tree_height) - bottom_tree_index;
        int bottom_tree_range_left = range_left + (bottom_tree_index << (bottom_tree_og_height - 1));
        items[bottom_tree_range_left] = max(this->tree[bottom_tree_block_index], this->tree[bottom_tree_block_index + bottom_tree_size]);
    }

    //update upper tree
    this->range_update(block_index, top_tree_height, range_left, og_height, query_range_left, query_range_right, items);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %r8d, 0x28(%rsp)
movl %ecx, %r10d
movq %rsi, 0x40(%rsp)
movq 0x98(%rsp), %r15
cmpl $0x1, %edx
je 0x19c0
movl 0x90(%rsp), %ebp
movl %r9d, %eax
subl %r10d, %eax
movl %eax, 0x24(%rsp)
movl %ebp, %eax
subl %r10d, %eax
movl %eax, 0x20(%rsp)
leal -0x1(%r10), %ebx
movq 0x40(%rsp), %rax
leal -0x1(%rax), %ecx
movl %ecx, 0x8(%rsp)
addl $-0x2, %eax
movl %eax, 0x1c(%rsp)
movq %r10, 0x50(%rsp)
movl %r9d, 0x14(%rsp)
movl %ebx, 0x30(%rsp)
movslq %edx, %rdx
leaq 0x280f(%rip), %rax      # 0x4040
movl (%rax,%rdx,4), %r12d
subl %r12d, %edx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %edx, %ecx
shll %cl, %eax
movl %eax, 0xc(%rsp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %r12d, %ecx
shll %cl, %eax
movl %eax, 0x2c(%rsp)
movl 0x28(%rsp), %eax
movl %eax, %r8d
movq %rdx, 0x48(%rsp)
subl %edx, %r8d
leal -0x1(%r8), %r11d
movl 0x24(%rsp), %eax
movl %r11d, %ecx
sarl %cl, %eax
movl 0x20(%rsp), %edx
sarl %cl, %edx
movl %eax, 0x10(%rsp)
cmpl %edx, %eax
movl %edx, 0x18(%rsp)
jg 0x1937
movl 0x8(%rsp), %r14d
movl 0x10(%rsp), %eax
subl %eax, %r14d
subl 0xc(%rsp), %r14d
movl %eax, %r13d
movl %r12d, 0x38(%rsp)
movl %r11d, 0x34(%rsp)
movl %r13d, %esi
movl %r12d, %ecx
shll %cl, %esi
movl %r13d, %eax
movl %r11d, %ecx
shll %cl, %eax
addl %r14d, %esi
addl %r10d, %eax
cmpl %r9d, %eax
movl 0x14(%rsp), %r9d
cmovgl %eax, %r9d
leal 0x1(%r13), %ecx
movl %ecx, 0x3c(%rsp)
movl %ecx, %r10d
movl %r11d, %ecx
shll %cl, %r10d
addl %ebx, %r10d
cmpl %ebp, %r10d
cmovgel %ebp, %r10d
movl %r12d, %edx
movl %eax, %ecx
pushq %r15
pushq %r10
movl %ebp, %ebx
movq %r15, %rbp
movq %rdi, %r15
movq %r8, %r12
callq 0x17bc
movq %r12, %r8
movl 0x44(%rsp), %r11d
movl 0x28(%rsp), %edx
movq %r15, %rdi
movq %rbp, %r15
movl %ebx, %ebp
movl 0x40(%rsp), %ebx
movl 0x48(%rsp), %r12d
movq 0x60(%rsp), %r10
movl 0x24(%rsp), %r9d
addq $0x10, %rsp
decl %r14d
cmpl %edx, %r13d
movl 0x3c(%rsp), %eax
movl %eax, %r13d
jne 0x18a3
movl 0x10(%rsp), %r13d
andl $-0x2, %r13d
cmpl %edx, %r13d
jg 0x19b2
movl %r11d, %r14d
movq (%rdi), %rax
movl 0x1c(%rsp), %edx
movl 0xc(%rsp), %r8d
subl %r8d, %edx
subl 0x2c(%rsp), %edx
subl %r13d, %edx
movl 0x8(%rsp), %ecx
movl %ecx, %esi
subl %r8d, %esi
subl %r13d, %esi
movl %r13d, %r11d
movl %r12d, %ecx
shll %cl, %r11d
movl %r13d, %r8d
movl %r14d, %ecx
shll %cl, %r8d
leal (%rsi,%r11), %ecx
addl %r10d, %r8d
movslq %ecx, %rcx
addl %edx, %r11d
movslq %r11d, %r11
movl (%rax,%rcx,4), %ecx
movl (%rax,%r11,4), %r11d
cmpl %r11d, %ecx
cmovgl %ecx, %r11d
movslq %r8d, %rcx
movl %r11d, (%r15,%rcx,4)
addl $0x2, %r13d
addl $-0x2, %edx
addl $-0x2, %esi
cmpl 0x18(%rsp), %r13d
jle 0x196a
movq 0x48(%rsp), %rdx
cmpl $0x1, %edx
jne 0x1827
movslq %r10d, %rax
movl (%r15,%rax,4), %eax
movq (%rdi), %rcx
movslq 0x40(%rsp), %rdx
movl %eax, (%rcx,%rdx,4)
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop