// File: /workspace/github_cpp_makefile_star2_O3/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 0x10(%rsp), %rdi
movapd %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
movq 0x8(%rbx), %rsi
subq (%rbx), %rsi
sarq %rsi
callq 0x157e
xorl %r14d, %r14d
leaq 0x30(%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 0x15b0
movabsq $-0x8000000000000000, %rax # imm = 0x8000000000000000
movq (%rbx), %rdx
movq %rbx, 0x8(%rsp)
movq 0x8(%rbx), %rsi
subq %rdx, %rsi
shrq $0x2, %rsi
movq 0x30(%rsp), %rdi
movq 0x10(%rsp), %r8
movl $0x0, %r9d
testl %esi, %esi
jle 0x2235
movq 0x8(%rsp), %rcx
movq 0x18(%rcx), %r10
movl %esi, %r11d
andl $0x7fffffff, %r11d      # imm = 0x7FFFFFFF
xorl %r9d, %r9d
leaq 0x3f(%rax), %r15
xorl %r14d, %r14d
movl %r9d, %ecx
shrl $0x6, %ecx
movq (%r10,%rcx,8), %rcx
btq %r9, %rcx
jae 0x222a
movl (%rdx,%r9,4), %r12d
cmpl %ebp, %r12d
jg 0x2235
movslq %r14d, %rcx
leal 0x3f(%rcx), %r14d
testl %ecx, %ecx
cmovnsl %ecx, %r14d
sarl $0x6, %r14d
movslq %r14d, %r14
movq %rcx, %r13
andq %r15, %r13
xorl %ebx, %ebx
cmpq %rax, %r13
setbe %bl
movl $0x1, %r13d
shlq %cl, %r13
leaq (%rdi,%r14,8), %r14
orq %r13, -0x8(%r14,%rbx,8)
leal 0x1(%rcx), %r14d
movl %r12d, (%r8,%rcx,4)
incq %r9
cmpq %r9, %r11
jne 0x21d5
movl %esi, %r9d
movslq %r14d, %rcx
leal 0x3f(%rcx), %r10d
testl %ecx, %ecx
cmovnsl %r14d, %r10d
sarl $0x6, %r10d
movslq %r10d, %r11
leaq 0x3f(%rax), %r10
movq %rcx, %rbx
andq %r10, %rbx
xorl %r15d, %r15d
cmpq %rax, %rbx
setbe %r15b
movl $0x1, %ebx
shlq %cl, %rbx
leaq (%rdi,%r11,8), %r11
orq %rbx, -0x8(%r11,%r15,8)
movl %ebp, (%r8,%rcx,4)
cmpl %esi, %r9d
movq 0x8(%rsp), %r12
jge 0x22de
incl %r14d
movq 0x18(%r12), %r11
movl %r9d, %r9d
movl %r9d, %ecx
shrl $0x6, %ecx
movq (%r11,%rcx,8), %rcx
btq %r9, %rcx
jae 0x22d6
movslq %r14d, %rcx
leal 0x3f(%rcx), %ebx
testl %ecx, %ecx
cmovnsl %ecx, %ebx
sarl $0x6, %ebx
movslq %ebx, %rbx
movq %rcx, %r14
andq %r10, %r14
xorl %r15d, %r15d
cmpq %rax, %r14
setbe %r15b
movl $0x1, %r14d
shlq %cl, %r14
leaq (%rdi,%rbx,8), %rbx
orq %r14, -0x8(%rbx,%r15,8)
movl (%rdx,%r9,4), %ebx
leal 0x1(%rcx), %r14d
movl %ebx, (%r8,%rcx,4)
incq %r9
cmpl %esi, %r9d
jl 0x2287
leaq 0x10(%rsp), %rsi
movq %r12, %rdi
callq 0x2710
leaq 0x18(%r12), %rdi
leaq 0x30(%rsp), %rsi
callq 0x27f4
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 0x2364
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, 0x28(%rsp)
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
callq 0x1170
movsd 0x28(%rsp), %xmm1
subsd %xmm0, %xmm1
cvttsd2si %xmm1, %edx
movl %edx, 0x54(%r12)
movq %r12, %rdi
xorl %esi, %esi
callq 0x28ae
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x23be
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x10f0
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x23d5
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x10f0
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x23ed
jmp 0x23ed
movq %rax, %rbx
jmp 0x2407
movq %rax, %rbx
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x2407
movq 0x50(%rsp), %rsi
subq %rdi, %rsi
callq 0x10f0
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x241e
movq 0x20(%rsp), %rsi
subq %rdi, %rsi
callq 0x10f0
movq %rbx, %rdi
callq 0x1160