// File: mouda[P]LTE_random_access-simulate/alglibinternal.cpp
// Function: alglib_impl::tagsortbuf(alglib_impl::ae_vector*, long, alglib_impl::ae_vector*, alglib_impl::ae_vector*, alglib_impl::apbuffers*, alglib_impl::ae_state*)
void tagsortbuf(/* Real    */ ae_vector* a,
     ae_int_t n,
     /* Integer */ ae_vector* p1,
     /* Integer */ ae_vector* p2,
     apbuffers* buf,
     ae_state *_state)
{
    ae_int_t i;
    ae_int_t lv;
    ae_int_t lp;
    ae_int_t rv;
    ae_int_t rp;


    
    /*
     * Special cases
     */
    if( n<=0 )
    {
        return;
    }
    if( n==1 )
    {
        ivectorsetlengthatleast(p1, 1, _state);
        ivectorsetlengthatleast(p2, 1, _state);
        p1->ptr.p_int[0] = 0;
        p2->ptr.p_int[0] = 0;
        return;
    }
    
    /*
     * General case, N>1: prepare permutations table P1
     */
    ivectorsetlengthatleast(p1, n, _state);
    for(i=0; i<=n-1; i++)
    {
        p1->ptr.p_int[i] = i;
    }
    
    /*
     * General case, N>1: sort, update P1
     */
    rvectorsetlengthatleast(&buf->ra0, n, _state);
    ivectorsetlengthatleast(&buf->ia0, n, _state);
    tagsortfasti(a, p1, &buf->ra0, &buf->ia0, n, _state);
    
    /*
     * General case, N>1: fill permutations table P2
     *
     * To fill P2 we maintain two arrays:
     * * PV (Buf.IA0), Position(Value). PV[i] contains position of I-th key at the moment
     * * VP (Buf.IA1), Value(Position). VP[i] contains key which has position I at the moment
     *
     * At each step we making permutation of two items:
     *   Left, which is given by position/value pair LP/LV
     *   and Right, which is given by RP/RV
     * and updating PV[] and VP[] correspondingly.
     */
    ivectorsetlengthatleast(&buf->ia0, n, _state);
    ivectorsetlengthatleast(&buf->ia1, n, _state);
    ivectorsetlengthatleast(p2, n, _state);
    for(i=0; i<=n-1; i++)
    {
        buf->ia0.ptr.p_int[i] = i;
        buf->ia1.ptr.p_int[i] = i;
    }
    for(i=0; i<=n-1; i++)
    {
        
        /*
         * calculate LP, LV, RP, RV
         */
        lp = i;
        lv = buf->ia1.ptr.p_int[lp];
        rv = p1->ptr.p_int[i];
        rp = buf->ia0.ptr.p_int[rv];
        
        /*
         * Fill P2
         */
        p2->ptr.p_int[i] = rp;
        
        /*
         * update PV and VP
         */
        buf->ia1.ptr.p_int[lp] = rv;
        buf->ia1.ptr.p_int[rp] = lv;
        buf->ia0.ptr.p_int[lv] = rp;
        buf->ia0.ptr.p_int[rv] = lp;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
cmpq $0x0, -0x10(%rbp)
jg 0x202cc
jmp 0x2050f
cmpq $0x1, -0x10(%rbp)
jne 0x2031a
movq -0x18(%rbp), %rdi
movq -0x30(%rbp), %rdx
movl $0x1, %esi
callq 0x1e330
movq -0x20(%rbp), %rdi
movq -0x30(%rbp), %rdx
movl $0x1, %esi
callq 0x1e330
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movq $0x0, (%rax)
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq $0x0, (%rax)
jmp 0x2050f
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x1e330
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jg 0x20366
movq -0x38(%rbp), %rdx
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x38(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x20333
movq -0x28(%rbp), %rdi
addq $0xc0, %rdi
movq -0x10(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x1e370
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x1e330
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x28(%rbp), %rdx
addq $0xc0, %rdx
movq -0x28(%rbp), %rcx
movq -0x10(%rbp), %r8
movq -0x30(%rbp), %r9
callq 0x20520
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x1e330
movq -0x28(%rbp), %rdi
addq $0x30, %rdi
movq -0x10(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x1e330
movq -0x20(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x30(%rbp), %rdx
callq 0x1e330
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jg 0x20439
movq -0x38(%rbp), %rdx
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x38(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x38(%rbp), %rdx
movq -0x28(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x38(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x203f2
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jg 0x2050f
movq -0x38(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x28(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x38(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x50(%rbp)
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rdx
movq -0x20(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x38(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x50(%rbp), %rdx
movq -0x28(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x48(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x40(%rbp), %rdx
movq -0x28(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x58(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x58(%rbp), %rdx
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x40(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x48(%rbp), %rdx
movq -0x28(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x50(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x20441
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)