// File: /workspace/github_cpp_makefile_star2_O1/reddragon[P]packed-memory-array/impl1.cpp
// Function: PackedMemoryArray<int>::expand_PMA(int)
void PackedMemoryArray<E>::expand_PMA(E e) {
    // Create a new store
    std::vector<E> new_store;
    new_store.resize(store.size() * 2);
    std::vector<bool> new_exists;
    new_exists.resize((int)ceil(s+1));
    
    int count = 0, i;
    // Insert all elements less than e
    for(i = 0; i < (int)store.size(); i++) 
        if(ELEM_EXISTS_AT(i)) {
            if(store[i] > e)
                break;
            new_exists[count] = 1;
            new_store[count++] = store[i];
        }
    
    // Insert the element we wanted
    new_exists[count] = 1;
    new_store[count++] = e;
    
    // Insert rest of the elements
    for(; i < (int)store.size(); i++) 
        if(ELEM_EXISTS_AT(i)) {
            new_exists[count] = 1;
            new_store[count++] = store[i];
        }

    // Replace the existing store and bitmask
    store = new_store;
    exists = new_exists;
 
    // Increment the number of elements in the PMA
    s++;
    
    // std::cout << "Old smallest window size: " << segment_size << std::endl;
    // Recalculate l and segment_size
    int log2n = __builtin_popcount(store.size()-1);
    if(log2n & (log2n-1)) {
        // log2n is not a power of 2, round it up to the nearest power of 2.
        segment_size = 1<<((int)floor(log2(log2n<<1)));
    }
    else {
        // log2n is a power of 2, so, all is fine.
        segment_size = 1<<log2n;
    }
    l = log2n - log2(segment_size);
    // std::cout << "New smallest window size: " << segment_size << std::endl;

    // Now rebalance the entire PMA 
    rebalance(0, l);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %esi, %ebp
movq %rdi, %rbx
xorpd %xmm0, %xmm0
leaq 0x30(%rsp), %rdi
movapd %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
movq 0x8(%rbx), %rsi
subq (%rbx), %rsi
sarq %rsi
callq 0x1590
xorl %r14d, %r14d
movq %rsp, %rdi
movq %r14, (%rdi)
movl %r14d, 0x8(%rdi)
movq %r14, 0x10(%rdi)
movl %r14d, 0x18(%rdi)
movq %r14, 0x20(%rdi)
movl 0x58(%rbx), %eax
incl %eax
movslq %eax, %rsi
xorl %edx, %edx
callq 0x15c2
movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000
movq (%rbx), %rdx
movq %rbx, 0x28(%rsp)
movq 0x8(%rbx), %rsi
subq %rdx, %rsi
shrq $0x2, %rsi
movl $0x0, %edi
testl %esi, %esi
jle 0x2264
movq 0x28(%rsp), %rcx
movq 0x18(%rcx), %r8
movq (%rsp), %r9
movq 0x30(%rsp), %r10
movl %esi, %r11d
andl $0x7fffffff, %r11d      # imm = 0x7FFFFFFF
xorl %edi, %edi
leaq 0x3f(%rax), %r15
xorl %r14d, %r14d
movq %rdi, %rcx
shrq $0x6, %rcx
movq (%r8,%rcx,8), %rcx
btq %rdi, %rcx
jae 0x225a
movl (%rdx,%rdi,4), %r12d
cmpl %ebp, %r12d
jg 0x2264
movslq %r14d, %rcx
leaq 0x3f(%rcx), %r14
testq %rcx, %rcx
cmovnsq %rcx, %r14
sarq $0x6, %r14
movq %rcx, %r13
andq %r15, %r13
xorl %ebx, %ebx
cmpq %rax, %r13
setbe %bl
movl $0x1, %r13d
shlq %cl, %r13
leaq (%r9,%r14,8), %r14
orq %r13, -0x8(%r14,%rbx,8)
leal 0x1(%rcx), %r14d
movl %r12d, (%r10,%rcx,4)
incq %rdi
cmpq %rdi, %r11
jne 0x2206
movl %esi, %edi
movslq %r14d, %rcx
movq (%rsp), %r8
leaq 0x3f(%rcx), %r10
testq %rcx, %rcx
cmovnsq %rcx, %r10
sarq $0x6, %r10
leaq 0x3f(%rax), %r9
movq %rcx, %r11
andq %r9, %r11
xorl %ebx, %ebx
cmpq %rax, %r11
setbe %bl
movl $0x1, %r11d
shlq %cl, %r11
leaq (%r8,%r10,8), %r10
orq %r11, -0x8(%r10,%rbx,8)
movq 0x30(%rsp), %r10
movl %ebp, (%r10,%rcx,4)
cmpl %esi, %edi
movq 0x28(%rsp), %r12
jge 0x2311
incl %r14d
movq 0x18(%r12), %r11
movl %edi, %edi
movq %rdi, %rcx
shrq $0x6, %rcx
movq (%r11,%rcx,8), %rcx
btq %rdi, %rcx
jae 0x230a
movslq %r14d, %rcx
leaq 0x3f(%rcx), %rbx
testq %rcx, %rcx
cmovnsq %rcx, %rbx
sarq $0x6, %rbx
movq %rcx, %r14
andq %r9, %r14
xorl %r15d, %r15d
cmpq %rax, %r14
setbe %r15b
movl $0x1, %r14d
shlq %cl, %r14
leaq (%r8,%rbx,8), %rbx
orq %r14, -0x8(%rbx,%r15,8)
movl (%rdx,%rdi,4), %ebx
leal 0x1(%rcx), %r14d
movl %ebx, (%r10,%rcx,4)
incq %rdi
cmpl %esi, %edi
jl 0x22ba
leaq 0x30(%rsp), %rsi
movq %r12, %rdi
callq 0x2756
leaq 0x18(%r12), %rdi
movq %rsp, %rsi
callq 0x282c
incl 0x58(%r12)
movq 0x8(%r12), %rax
subq (%r12), %rax
shrq $0x2, %rax
decl %eax
movl %eax, %ecx
shrl %ecx
andl $0x55555555, %ecx       # imm = 0x55555555
subl %ecx, %eax
movl $0x33333333, %ecx       # imm = 0x33333333
movl %eax, %edx
andl %ecx, %edx
shrl $0x2, %eax
andl %ecx, %eax
addl %edx, %eax
movl %eax, %ecx
shrl $0x4, %ecx
addl %eax, %ecx
andl $0xf0f0f0f, %ecx        # imm = 0xF0F0F0F
imull $0x1010101, %ecx, %r14d # imm = 0x1010101
shrl $0x18, %r14d
leal -0x1(%r14), %eax
movl %r14d, %ecx
testl %eax, %r14d
je 0x2395
leal (%r14,%r14), %eax
cvtsi2sd %eax, %xmm0
callq 0x1170
callq 0x1150
cvttsd2si %xmm0, %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, 0x5c(%r12)
xorps %xmm0, %xmm0
cvtsi2sd %r14d, %xmm0
movsd %xmm0, 0x50(%rsp)
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
callq 0x1170
movsd 0x50(%rsp), %xmm1
subsd %xmm0, %xmm1
cvttsd2si %xmm1, %edx
movl %edx, 0x54(%r12)
movq %r12, %rdi
xorl %esi, %esi
callq 0x28cc
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x2406
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x10f0
xorl %eax, %eax
movq %rax, (%rsp)
movl %eax, 0x8(%rsp)
movq %rax, 0x10(%rsp)
movl %eax, 0x18(%rsp)
movq %rax, 0x20(%rsp)
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x241d
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x10f0
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2435
jmp 0x2435
movq %rax, %rbx
jmp 0x2466
movq %rax, %rbx
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x2466
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x10f0
xorl %eax, %eax
movq %rax, (%rsp)
movl %eax, 0x8(%rsp)
movq %rax, 0x10(%rsp)
movl %eax, 0x18(%rsp)
movq %rax, 0x20(%rsp)
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x247d
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x10f0
movq %rbx, %rdi
callq 0x1160
nop