// File: /workspace/github_cpp_makefile_star2_O2/NinjaDevelper[P]ReedSolomon/cxx/ReedSolomon.cpp
// Function: ReedSolomon::correct(POLY&, int, std::vector<int, std::allocator<int>>&)
POLY& ReedSolomon::correct(POLY& msg, int num,vector<int>& pos){
    int i=0;
    int j=0;
    int errNum=pos.size();
    unsigned char *tmp=(unsigned char *)malloc(errNum<<1);

    //calculate syndrome
    unsigned char *synd=(unsigned char *)malloc(num);
    for(i=0;i<num;i++){
        synd[i] = evaluatePoly(msg, expTable[i]);
    }

    //calculate locator
    POLY locator={(unsigned char *)malloc(errNum+1),1};
    locator.data[0]=1;
    unsigned char c[2]={0,1};
    POLY p={c,2};
    for(i=0;i<errNum;i++){
        c[0] = expTable[msg.n-1-pos[i]];
        multiplyPoly(locator,p,tmp);
    }

    //calculate evaluator
    POLY evaluator={(unsigned char *)malloc(errNum<<1),errNum};
    for(i=0;i<errNum;i++){
        evaluator.data[i]=synd[errNum-i-1];
    }
    multiplyPoly(evaluator, locator,tmp);
    for(i=0;i<errNum;i++){
        evaluator.data[i]=evaluator.data[evaluator.n-errNum+i];
    }
    evaluator.n=errNum;

    //calculate derivation of locator
    for(j=0,i=((locator.n & 0x1) ==0? 0:1);i<locator.n;i+=2,j++){
        locator.data[j]=locator.data[i];
    }
    locator.n=((locator.n & 0x1) ==0? locator.n>>1:(locator.n-1)>>1);

    /* calculate X_j*evaluator(X_j-^1)/locator'(X_j^-1)=
     * evaluator(X_j-^1)/( X_j^-1 * locator'(X_j^-1))
     */
    for(i=0;i<errNum;i++){
        unsigned char minus_i = expTable[pos[i]+256-msg.n];
        unsigned char evaluator_minus_i = evaluatePoly(evaluator, minus_i);
        unsigned char locator_minus_i = evaluatePoly(locator, 
                                multiply(evaluator_minus_i,evaluator_minus_i));
        msg.data[pos[i]] ^= divide(evaluator_minus_i, 
                                   multiply(minus_i,locator_minus_i));
    }
    free(tmp);
    free(synd);
    free(locator.data);
    free(evaluator.data);
    return msg;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movl %edx, %ebp
movq %rsi, 0x8(%rsp)
movq %rdi, %r15
movq 0x8(%rcx), %rbx
movq %rcx, 0x40(%rsp)
subq (%rcx), %rbx
movq %rbx, %rax
shrq $0x2, %rax
movq %rax, 0x10(%rsp)
addl %eax, %eax
movslq %eax, %rdi
movq %rdi, 0x48(%rsp)
callq 0x21a0
movq %rax, %r13
movslq %ebp, %r12
movq %r12, %rdi
callq 0x21a0
movq %rax, 0x18(%rsp)
xorl %r14d, %r14d
testl %r12d, %r12d
cmovlel %r14d, %r12d
cmpq %r14, %r12
je 0x2675
movzbl (%r15,%r14), %edx
movq %r15, %rdi
movq 0x8(%rsp), %rsi
callq 0x2464
movq 0x18(%rsp), %rcx
movb %al, (%rcx,%r14)
incq %r14
jmp 0x2650
shlq $0x1e, %rbx
movabsq $0x100000000, %rdi      # imm = 0x100000000
addq %rbx, %rdi
sarq $0x20, %rdi
callq 0x21a0
leaq 0x30(%rsp), %rbp
movq %rax, (%rbp)
movl $0x1, 0x8(%rbp)
movb $0x1, (%rax)
leaq 0x6(%rsp), %rax
movw $0x100, (%rax)          # imm = 0x100
leaq 0x58(%rsp), %r12
movq %rax, (%r12)
movl $0x2, 0x8(%r12)
xorl %ebx, %ebx
movq 0x10(%rsp), %rax
testl %eax, %eax
movl $0x0, %r14d
cmovgl %eax, %r14d
cmpq %rbx, %r14
je 0x270b
movq 0x40(%rsp), %rax
movq (%rax), %rax
movl (%rax,%rbx,4), %eax
notl %eax
movq 0x8(%rsp), %rcx
addl 0x8(%rcx), %eax
cltq
movb (%r15,%rax), %al
movb %al, 0x6(%rsp)
movq %r15, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movq %r13, %rcx
callq 0x23b2
incq %rbx
jmp 0x26d1
movabsq $-0x100000000, %rbx     # imm = 0xFFFFFFFF00000000
movq 0x48(%rsp), %rdi
callq 0x21a0
movq %rax, 0x20(%rsp)
movq 0x10(%rsp), %r12
movl %r12d, 0x28(%rsp)
movq %r12, %rcx
shlq $0x20, %rcx
addq %rbx, %rcx
xorl %edx, %edx
movq 0x18(%rsp), %rdi
cmpq %rdx, %r14
je 0x275b
movq %rcx, %rsi
sarq $0x20, %rsi
movb (%rdi,%rsi), %sil
movb %sil, (%rax,%rdx)
incq %rdx
addq %rbx, %rcx
jmp 0x273f
leaq 0x20(%rsp), %rsi
leaq 0x30(%rsp), %rdx
movq %r15, %rdi
movq %r13, %rcx
callq 0x23b2
movl %r12d, %eax
negl %eax
xorl %ecx, %ecx
cmpq %rcx, %r14
je 0x2798
movq 0x20(%rsp), %rdx
leal (%rax,%rcx), %esi
addl 0x28(%rsp), %esi
movslq %esi, %rsi
movb (%rdx,%rsi), %sil
movb %sil, (%rdx,%rcx)
incq %rcx
jmp 0x2777
movl %r12d, 0x28(%rsp)
movl 0x38(%rsp), %ecx
movl %ecx, %eax
andl $0x1, %eax
xorl %edx, %edx
movslq %ecx, %rsi
cmpq %rsi, %rax
jge 0x27ca
movq 0x30(%rsp), %rcx
movb (%rcx,%rax), %sil
movb %sil, (%rcx,%rdx)
addq $0x2, %rax
incq %rdx
movl 0x38(%rsp), %ecx
jmp 0x27a8
movq %r13, 0x10(%rsp)
sarl %ecx
leaq 0x30(%rsp), %rax
movl %ecx, 0x8(%rax)
xorl %r13d, %r13d
movq %r14, 0x50(%rsp)
cmpq %r13, %r14
je 0x28bc
movq 0x40(%rsp), %rax
movq (%rax), %rax
movslq (%rax,%r13,4), %rbx
movq 0x8(%rsp), %rax
movl 0x8(%rax), %eax
movl %ebx, %ecx
subl %eax, %ecx
addl $0x100, %ecx            # imm = 0x100
movslq %ecx, %rax
movzbl (%r15,%rax), %ebp
movq %r15, %rdi
leaq 0x20(%rsp), %rsi
movl %ebp, %edx
callq 0x2464
movl %eax, %r12d
movzbl %al, %r14d
testb %al, %al
je 0x2839
movzbl 0x200(%r15,%r14), %eax
movb (%r15,%rax,2), %al
jmp 0x283b
xorl %eax, %eax
movzbl %al, %edx
movq %r15, %rdi
leaq 0x30(%rsp), %rsi
callq 0x2464
movb $-0x1, %cl
testq %rbp, %rbp
je 0x28a4
testb %al, %al
je 0x28a4
movzbl 0x200(%r15,%rbp), %ecx
movzbl %al, %eax
movzbl 0x200(%r15,%rax), %eax
addq %rcx, %rax
movzbl (%r15,%rax), %eax
cmpq $0x1, %rax
movl $0x0, %ecx
sbbl %ecx, %ecx
testb %r12b, %r12b
je 0x28a4
testb %al, %al
je 0x28a4
movzbl 0x200(%r15,%r14), %ecx
movzbl 0x200(%r15,%rax), %eax
subq %rax, %rcx
movb 0xff(%rcx,%r15), %cl
movq 0x8(%rsp), %rax
movq (%rax), %rax
xorb %cl, (%rax,%rbx)
incq %r13
movq 0x50(%rsp), %r14
jmp 0x27e1
movq 0x10(%rsp), %rdi
callq 0x2190
movq 0x18(%rsp), %rdi
callq 0x2190
movq 0x30(%rsp), %rdi
callq 0x2190
movq 0x20(%rsp), %rdi
callq 0x2190
movq 0x8(%rsp), %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq