// File: 6851-2021[P]Cache-Oblivious-Data-Structures/static_search_trees/static_search_trees.cpp
// Function: co_static_search_tree::get(int, int, int, int, int)
int co_static_search_tree::get(int block_index, int height, int range_left, int og_height, int value) {
    if (height == 1)
    {
        return range_left;
    }
    if(height == 2) {
        if(value <= this->tree[block_index + 1])
            return range_left;
        return range_left + (1 << (og_height - 2));
    }
    if(height == 3){
        return this->get_3_base_case(block_index, range_left, og_height, value);
    }
    if(height == 4) {
        return this->get_4_base_case(block_index, range_left, og_height, value);
    }

    
    int bottom_tree_height = bottom_tree_height_memo[height];
    int top_tree_height = height - bottom_tree_height;

    int index = this->get(block_index, top_tree_height, range_left, og_height, value);
    
    int top_tree_size = (1 << top_tree_height) - 1;

    int bottom_tree_og_height = og_height - top_tree_height;
    int bottom_tree_index = (index - range_left) >> (bottom_tree_og_height - 1);
    int bottom_tree_size = (1 << bottom_tree_height) - 1;

    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));

    if (value <= tree[bottom_tree_block_index]){
        return this->get(bottom_tree_block_index, bottom_tree_height, bottom_tree_range_left, bottom_tree_og_height, value);
    }
    else{
        bottom_tree_index += 1;
        bottom_tree_block_index += bottom_tree_size;
        bottom_tree_range_left += (1 << (bottom_tree_og_height - 1));
        return this->get(bottom_tree_block_index, bottom_tree_height, bottom_tree_range_left, bottom_tree_og_height, value);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movl %r8d, -0x20(%rbp)
movl %r9d, -0x24(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpl $0x1, -0x18(%rbp)
jne 0x1716
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x18b3
cmpl $0x2, -0x18(%rbp)
jne 0x175b
movq -0x50(%rbp), %rcx
movl -0x24(%rbp), %eax
movq (%rcx), %rcx
movl -0x14(%rbp), %edx
addl $0x1, %edx
movslq %edx, %rdx
cmpl (%rcx,%rdx,4), %eax
jg 0x173f
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x18b3
movl -0x1c(%rbp), %eax
movl -0x20(%rbp), %ecx
subl $0x2, %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
addl %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0x18b3
cmpl $0x3, -0x18(%rbp)
jne 0x177f
movq -0x50(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x1c(%rbp), %edx
movl -0x20(%rbp), %ecx
movl -0x24(%rbp), %r8d
callq 0x3cc0
movl %eax, -0x4(%rbp)
jmp 0x18b3
cmpl $0x4, -0x18(%rbp)
jne 0x17a3
movq -0x50(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x1c(%rbp), %edx
movl -0x20(%rbp), %ecx
movl -0x24(%rbp), %r8d
callq 0x3d80
movl %eax, -0x4(%rbp)
jmp 0x18b3
movq -0x50(%rbp), %rdi
movslq -0x18(%rbp), %rcx
leaq 0x585e(%rip), %rax      # 0x7010
movl (%rax,%rcx,4), %eax
movl %eax, -0x28(%rbp)
movl -0x18(%rbp), %eax
subl -0x28(%rbp), %eax
movl %eax, -0x2c(%rbp)
movl -0x14(%rbp), %esi
movl -0x2c(%rbp), %edx
movl -0x1c(%rbp), %ecx
movl -0x20(%rbp), %r8d
movl -0x24(%rbp), %r9d
callq 0x16e0
movl %eax, -0x30(%rbp)
movl -0x2c(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
subl $0x1, %eax
movl %eax, -0x34(%rbp)
movl -0x20(%rbp), %eax
subl -0x2c(%rbp), %eax
movl %eax, -0x38(%rbp)
movl -0x30(%rbp), %eax
subl -0x1c(%rbp), %eax
movl -0x38(%rbp), %ecx
subl $0x1, %ecx
sarl %cl, %eax
movl %eax, -0x3c(%rbp)
movl -0x28(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
subl $0x1, %eax
movl %eax, -0x40(%rbp)
movl -0x14(%rbp), %eax
addl -0x34(%rbp), %eax
movl -0x3c(%rbp), %edx
movl -0x28(%rbp), %ecx
shll %cl, %edx
movl %edx, %ecx
addl %ecx, %eax
subl -0x3c(%rbp), %eax
movl %eax, -0x44(%rbp)
movl -0x1c(%rbp), %eax
movl -0x3c(%rbp), %edx
movl -0x38(%rbp), %ecx
subl $0x1, %ecx
shll %cl, %edx
movq -0x50(%rbp), %rcx
addl %edx, %eax
movl %eax, -0x48(%rbp)
movl -0x24(%rbp), %eax
movq (%rcx), %rcx
movslq -0x44(%rbp), %rdx
cmpl (%rcx,%rdx,4), %eax
jg 0x1871
movq -0x50(%rbp), %rdi
movl -0x44(%rbp), %esi
movl -0x28(%rbp), %edx
movl -0x48(%rbp), %ecx
movl -0x38(%rbp), %r8d
movl -0x24(%rbp), %r9d
callq 0x16e0
movl %eax, -0x4(%rbp)
jmp 0x18b3
movq -0x50(%rbp), %rdi
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
movl -0x40(%rbp), %eax
addl -0x44(%rbp), %eax
movl %eax, -0x44(%rbp)
movl -0x38(%rbp), %ecx
subl $0x1, %ecx
movl $0x1, %eax
shll %cl, %eax
addl -0x48(%rbp), %eax
movl %eax, -0x48(%rbp)
movl -0x44(%rbp), %esi
movl -0x28(%rbp), %edx
movl -0x48(%rbp), %ecx
movl -0x38(%rbp), %r8d
movl -0x24(%rbp), %r9d
callq 0x16e0
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)