// File: xocoder[P]m_kcptun/vendor/cm256/cm256.cpp
// Function: CM256Decoder::Initialize(cm256_encoder_params_t&, cm256_block_t*)
bool CM256Decoder::Initialize(cm256_encoder_params& params, cm256_block* blocks)
{
    Params = params;

    cm256_block* block = blocks;
    OriginalCount = 0;
    RecoveryCount = 0;

    // Initialize erasures to zeros
    for (int ii = 0; ii < params.OriginalCount; ++ii)
    {
        ErasuresIndices[ii] = 0;
    }

    // For each input block,
    for (int ii = 0; ii < params.OriginalCount; ++ii, ++block)
    {
        int row = block->Index;

        // If it is an original block,
        if (row < params.OriginalCount)
        {
            Original[OriginalCount++] = block;

            if (ErasuresIndices[row] != 0)
            {
                // Error out if two row indices repeat
                return false;
            }

            ErasuresIndices[row] = 1;
        }
        else
        {
            Recovery[RecoveryCount++] = block;
        }
    }

    // Identify erasures
    for (int ii = 0, indexCount = 0; ii < 256; ++ii)
    {
        if (!ErasuresIndices[ii])
        {
            ErasuresIndices[indexCount] = static_cast<uint8_t>( ii );

            if (++indexCount >= RecoveryCount)
            {
                break;
            }
        }
    }

    return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rcx
movq (%rcx), %rdx
movq %rdx, (%rax)
movl 0x8(%rcx), %ecx
movl %ecx, 0x8(%rax)
movq -0x20(%rbp), %rcx
movq %rcx, -0x28(%rbp)
movl $0x0, 0x1018(%rax)
movl $0x0, 0x810(%rax)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpl (%rcx), %eax
jge 0xed41
movq -0x48(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movb $0x0, 0x101c(%rax,%rcx)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xed1b
movl $0x0, -0x30(%rbp)
movl -0x30(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpl (%rcx), %eax
jge 0xedfa
movq -0x28(%rbp), %rax
movzbl 0x8(%rax), %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
movq -0x18(%rbp), %rcx
cmpl (%rcx), %eax
jge 0xedbd
movq -0x48(%rbp), %rax
movq -0x28(%rbp), %rdx
movl 0x1018(%rax), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, 0x1018(%rax)
movslq %ecx, %rcx
movq %rdx, 0x818(%rax,%rcx,8)
movslq -0x34(%rbp), %rcx
movzbl 0x101c(%rax,%rcx), %eax
cmpl $0x0, %eax
je 0xedab
movb $0x0, -0x1(%rbp)
jmp 0xee5d
movq -0x48(%rbp), %rax
movslq -0x34(%rbp), %rcx
movb $0x1, 0x101c(%rax,%rcx)
jmp 0xedde
movq -0x48(%rbp), %rax
movq -0x28(%rbp), %rdx
movl 0x810(%rax), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, 0x810(%rax)
movslq %ecx, %rcx
movq %rdx, 0x10(%rax,%rcx,8)
jmp 0xede0
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
movq -0x28(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x28(%rbp)
jmp 0xed48
movl $0x0, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
cmpl $0x100, -0x38(%rbp)     # imm = 0x100
jge 0xee59
movq -0x48(%rbp), %rax
movslq -0x38(%rbp), %rcx
cmpb $0x0, 0x101c(%rax,%rcx)
jne 0xee4c
movq -0x48(%rbp), %rcx
movl -0x38(%rbp), %eax
movb %al, %dl
movslq -0x3c(%rbp), %rax
movb %dl, 0x101c(%rcx,%rax)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
cmpl 0x810(%rcx), %eax
jl 0xee4a
jmp 0xee59
jmp 0xee4c
jmp 0xee4e
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0xee08
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
popq %rbp
retq
nopw %cs:(%rax,%rax)