// File: mouda[P]LTE_random_access-simulate/ap.cpp
// Function: alglib_impl::_ialglib_rmv(long, long, double const*, double const*, double*, long, double, double)
void _ialglib_rmv(ae_int_t m, ae_int_t n, const double *a, const double *x, double *y, ae_int_t stride, double alpha, double beta)
{
    /*
     * Handle special cases:
     * - alpha is zero or n is zero
     * - m is zero
     */
    if( m==0 )
        return;
    if( alpha==0.0 || n==0 )
    {
        ae_int_t i;
        if( beta==0.0 )
        {
            for(i=0; i<m; i++)
            {
                *y = 0.0;
                y += stride;
            }
        }
        else
        {
            for(i=0; i<m; i++)
            {
                *y *= beta;
                y += stride;
            }
        }
        return;
    }
    
    /*
     * Handle general case: nonzero alpha, n and m
     *
     */
    if( m==32 && n==32 )
    {
        /*
         * 32x32, may be we have something better than general implementation
         */
        _ialglib_mv_32(a, x, y, stride, alpha, beta);
    }
    else
    {
        ae_int_t i, k, m2, n8, n2, ntrail2;
        const double *pa0, *pa1, *pb;

        /*
         * First M/2 rows of A are processed in pairs.
         * optimized code is used.
         */
        m2 = m/2;
        n8 = n/8;
        ntrail2 = (n-8*n8)/2;
        for(i=0; i<m2; i++)
        {
            double v0 = 0, v1 = 0;

            /*
             * 'a' points to the part of the matrix which
             * is not processed yet
             */
            pb = x;
            pa0 = a;
            pa1 = a+alglib_r_block;
            a += alglib_twice_r_block;

            /*
             * 8 elements per iteration
             */
            for(k=0; k<n8; k++)
            {
                v0 += pa0[0]*pb[0];
                v1 += pa1[0]*pb[0];
                v0 += pa0[1]*pb[1];
                v1 += pa1[1]*pb[1];
                v0 += pa0[2]*pb[2];
                v1 += pa1[2]*pb[2];
                v0 += pa0[3]*pb[3];
                v1 += pa1[3]*pb[3];
                v0 += pa0[4]*pb[4];
                v1 += pa1[4]*pb[4];
                v0 += pa0[5]*pb[5];
                v1 += pa1[5]*pb[5];
                v0 += pa0[6]*pb[6];
                v1 += pa1[6]*pb[6];
                v0 += pa0[7]*pb[7];
                v1 += pa1[7]*pb[7];
                pa0 += 8;
                pa1 += 8;
                pb  += 8;
            }

            /*
             * 2 elements per iteration
             */
            for(k=0; k<ntrail2; k++)
            {
                v0 += pa0[0]*pb[0];
                v1 += pa1[0]*pb[0];
                v0 += pa0[1]*pb[1];
                v1 += pa1[1]*pb[1];
                pa0 += 2;
                pa1 += 2;
                pb  += 2;
            }

            /*
             * last element, if needed
             */
            if( n%2!=0 )
            {
                v0 += pa0[0]*pb[0];
                v1 += pa1[0]*pb[0];
            }

            /*
             * final update
             */
            if( beta!=0 )
            {
                y[0] = beta*y[0]+alpha*v0;
                y[stride] = beta*y[stride]+alpha*v1;
            }
            else
            {
                y[0] = alpha*v0;
                y[stride] = alpha*v1;
            }
            
            /*
             * move to the next pair of elements
             */
            y+=2*stride;
        }


        /*
         * Last (odd) row is processed with less optimized code.
         */
        if( m%2!=0 )
        {
            double v0 = 0;

            /*
             * 'a' points to the part of the matrix which
             * is not processed yet
             */
            pb = x;
            pa0 = a;

            /*
             * 2 elements per iteration
             */
            n2 = n/2;
            for(k=0; k<n2; k++)
            {
                v0 += pa0[0]*pb[0]+pa0[1]*pb[1];
                pa0 += 2;
                pb  += 2;
            }

            /*
             * last element, if needed
             */
            if( n%2!=0 )
                v0 += pa0[0]*pb[0];

            /*
             * final update
             */
            if( beta!=0 )
                y[0] = beta*y[0]+alpha*v0;
            else
                y[0] = alpha*v0;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %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)
movsd %xmm0, -0x38(%rbp)
movsd %xmm1, -0x40(%rbp)
cmpq $0x0, -0x8(%rbp)
jne 0x4cf19
jmp 0x4d772
movsd -0x38(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x4cf2b
jp 0x4cf2b
jmp 0x4cf36
cmpq $0x0, -0x10(%rbp)
jne 0x4cfcb
movsd -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x4cf83
jp 0x4cf83
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq -0x8(%rbp), %rax
jge 0x4cf81
movq -0x28(%rbp), %rax
xorps %xmm0, %xmm0
movsd %xmm0, (%rax)
movq -0x30(%rbp), %rax
shlq $0x3, %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x4cf4e
jmp 0x4cfc6
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq -0x8(%rbp), %rax
jge 0x4cfc4
movsd -0x40(%rbp), %xmm0
movq -0x28(%rbp), %rax
mulsd (%rax), %xmm0
movsd %xmm0, (%rax)
movq -0x30(%rbp), %rax
shlq $0x3, %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x4cf8b
jmp 0x4cfc6
jmp 0x4d772
cmpq $0x20, -0x8(%rbp)
jne 0x4cffd
cmpq $0x20, -0x10(%rbp)
jne 0x4cffd
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
movq -0x30(%rbp), %rcx
movsd -0x38(%rbp), %xmm0
movsd -0x40(%rbp), %xmm1
callq 0x4cb50
jmp 0x4d772
movq -0x8(%rbp), %rax
movl $0x2, %ecx
cqto
idivq %rcx
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rax
movl $0x8, %ecx
cqto
idivq %rcx
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rax
movq -0x68(%rbp), %rcx
shlq $0x3, %rcx
subq %rcx, %rax
movl $0x2, %ecx
cqto
idivq %rcx
movq %rax, -0x78(%rbp)
movq $0x0, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x60(%rbp), %rax
jge 0x4d616
xorps %xmm0, %xmm0
movsd %xmm0, -0x98(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x18(%rbp), %rax
addq $0x100, %rax            # imm = 0x100
movq %rax, -0x88(%rbp)
movq -0x18(%rbp), %rax
addq $0x200, %rax            # imm = 0x200
movq %rax, -0x18(%rbp)
movq $0x0, -0x58(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x68(%rbp), %rax
jge 0x4d3d7
movq -0x80(%rbp), %rax
movsd (%rax), %xmm0
movq -0x90(%rbp), %rax
movsd (%rax), %xmm2
movsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movsd (%rax), %xmm0
movq -0x90(%rbp), %rax
movsd (%rax), %xmm2
movsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x80(%rbp), %rax
movsd 0x8(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x8(%rax), %xmm2
movsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movsd 0x8(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x8(%rax), %xmm2
movsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x80(%rbp), %rax
movsd 0x10(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x10(%rax), %xmm2
movsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movsd 0x10(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x10(%rax), %xmm2
movsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x80(%rbp), %rax
movsd 0x18(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x18(%rax), %xmm2
movsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movsd 0x18(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x18(%rax), %xmm2
movsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x80(%rbp), %rax
movsd 0x20(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x20(%rax), %xmm2
movsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movsd 0x20(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x20(%rax), %xmm2
movsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x80(%rbp), %rax
movsd 0x28(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x28(%rax), %xmm2
movsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movsd 0x28(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x28(%rax), %xmm2
movsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x80(%rbp), %rax
movsd 0x30(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x30(%rax), %xmm2
movsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movsd 0x30(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x30(%rax), %xmm2
movsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x80(%rbp), %rax
movsd 0x38(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x38(%rax), %xmm2
movsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movsd 0x38(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x38(%rax), %xmm2
movsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x80(%rbp), %rax
addq $0x40, %rax
movq %rax, -0x80(%rbp)
movq -0x88(%rbp), %rax
addq $0x40, %rax
movq %rax, -0x88(%rbp)
movq -0x90(%rbp), %rax
addq $0x40, %rax
movq %rax, -0x90(%rbp)
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0x4d0a4
movq $0x0, -0x58(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x78(%rbp), %rax
jge 0x4d4e4
movq -0x80(%rbp), %rax
movsd (%rax), %xmm0
movq -0x90(%rbp), %rax
movsd (%rax), %xmm2
movsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movsd (%rax), %xmm0
movq -0x90(%rbp), %rax
movsd (%rax), %xmm2
movsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x80(%rbp), %rax
movsd 0x8(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x8(%rax), %xmm2
movsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movsd 0x8(%rax), %xmm0
movq -0x90(%rbp), %rax
movsd 0x8(%rax), %xmm2
movsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xa0(%rbp)
movq -0x80(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x80(%rbp)
movq -0x88(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x88(%rbp)
movq -0x90(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x90(%rbp)
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0x4d3df
movq -0x10(%rbp), %rax
movl $0x2, %ecx
cqto
idivq %rcx
cmpq $0x0, %rdx
je 0x4d551
movq -0x80(%rbp), %rax
movsd (%rax), %xmm0
movq -0x90(%rbp), %rax
movsd (%rax), %xmm2
movsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x98(%rbp)
movq -0x88(%rbp), %rax
movsd (%rax), %xmm0
movq -0x90(%rbp), %rax
movsd (%rax), %xmm2
movsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xa0(%rbp)
movsd -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x4d563
jp 0x4d563
jmp 0x4d5c3
movsd -0x40(%rbp), %xmm0
movq -0x28(%rbp), %rax
movsd (%rax), %xmm2
movsd -0x38(%rbp), %xmm1
mulsd -0x98(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movq -0x28(%rbp), %rax
movsd %xmm0, (%rax)
movsd -0x40(%rbp), %xmm0
movq -0x28(%rbp), %rax
movq -0x30(%rbp), %rcx
movsd (%rax,%rcx,8), %xmm2
movsd -0x38(%rbp), %xmm1
mulsd -0xa0(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movq -0x28(%rbp), %rax
movq -0x30(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
jmp 0x4d5f2
movsd -0x38(%rbp), %xmm0
mulsd -0x98(%rbp), %xmm0
movq -0x28(%rbp), %rax
movsd %xmm0, (%rax)
movsd -0x38(%rbp), %xmm0
mulsd -0xa0(%rbp), %xmm0
movq -0x28(%rbp), %rax
movq -0x30(%rbp), %rcx
movsd %xmm0, (%rax,%rcx,8)
movq -0x30(%rbp), %rax
shlq %rax
shlq $0x3, %rax
addq -0x28(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x50(%rbp)
jmp 0x4d046
movq -0x8(%rbp), %rax
movl $0x2, %ecx
cqto
idivq %rcx
cmpq $0x0, %rdx
je 0x4d770
xorps %xmm0, %xmm0
movsd %xmm0, -0xa8(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x10(%rbp), %rax
movl $0x2, %ecx
cqto
idivq %rcx
movq %rax, -0x70(%rbp)
movq $0x0, -0x58(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x70(%rbp), %rax
jge 0x4d6dc
movq -0x80(%rbp), %rax
movsd (%rax), %xmm0
movq -0x90(%rbp), %rax
movsd (%rax), %xmm2
movq -0x80(%rbp), %rax
movsd 0x8(%rax), %xmm1
movq -0x90(%rbp), %rax
mulsd 0x8(%rax), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
addsd -0xa8(%rbp), %xmm0
movsd %xmm0, -0xa8(%rbp)
movq -0x80(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x80(%rbp)
movq -0x90(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x90(%rbp)
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
jmp 0x4d666
movq -0x10(%rbp), %rax
movl $0x2, %ecx
cqto
idivq %rcx
cmpq $0x0, %rdx
je 0x4d71b
movq -0x80(%rbp), %rax
movsd (%rax), %xmm0
movq -0x90(%rbp), %rax
movsd (%rax), %xmm2
movsd -0xa8(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0xa8(%rbp)
movsd -0x40(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomisd %xmm1, %xmm0
jne 0x4d72d
jp 0x4d72d
jmp 0x4d759
movsd -0x40(%rbp), %xmm0
movq -0x28(%rbp), %rax
movsd (%rax), %xmm2
movsd -0x38(%rbp), %xmm1
mulsd -0xa8(%rbp), %xmm1
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movq -0x28(%rbp), %rax
movsd %xmm0, (%rax)
jmp 0x4d76e
movsd -0x38(%rbp), %xmm0
mulsd -0xa8(%rbp), %xmm0
movq -0x28(%rbp), %rax
movsd %xmm0, (%rax)
jmp 0x4d770
jmp 0x4d772
addq $0xb0, %rsp
popq %rbp
retq
nopl (%rax,%rax)