// File: /workspace/github_cpp_makefile_star2_O3/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, %r14d
movq %rsi, %rbx
movq %rdi, %r15
movq 0x8(%rcx), %r13
movq %rcx, 0x50(%rsp)
subq (%rcx), %r13
movq %r13, %rax
shrq $0x2, %rax
movq %rax, 0x48(%rsp)
addl %eax, %eax
movslq %eax, %rdi
movq %rdi, 0x38(%rsp)
callq 0x2190
movq %rax, 0x10(%rsp)
movslq %r14d, %r12
movq %r12, %rdi
callq 0x2190
movq %rax, %rbp
testl %r12d, %r12d
jle 0x26cb
movl %r14d, %r14d
xorl %r12d, %r12d
movzbl (%r15,%r12), %edx
movq %r15, %rdi
movq %rbx, %rsi
callq 0x24a4
movb %al, (%rbp,%r12)
incq %r12
cmpq %r12, %r14
jne 0x26ae
movq %rbp, 0x40(%rsp)
shlq $0x1e, %r13
movabsq $0x100000000, %rdi      # imm = 0x100000000
addq %r13, %rdi
sarq $0x20, %rdi
callq 0x2190
movq %rax, 0x28(%rsp)
movl $0x1, 0x30(%rsp)
movb $0x1, (%rax)
leaq 0xe(%rsp), %rax
movw $0x100, (%rax)          # imm = 0x100
movq %rax, 0x58(%rsp)
movl $0x2, 0x60(%rsp)
movq 0x48(%rsp), %r14
testl %r14d, %r14d
jle 0x27f0
movl %r14d, %r13d
andl $0x7fffffff, %r13d      # imm = 0x7FFFFFFF
xorl %r14d, %r14d
movq %rbx, %rbp
movq 0x50(%rsp), %rbx
movq 0x10(%rsp), %r12
movq (%rbx), %rax
movl (%rax,%r14,4), %eax
notl %eax
addl 0x8(%rbp), %eax
cltq
movb (%r15,%rax), %al
movb %al, 0xe(%rsp)
movq %r15, %rdi
leaq 0x28(%rsp), %rsi
leaq 0x58(%rsp), %rdx
movq %r12, %rcx
callq 0x23ce
incq %r14
cmpq %r14, %r13
jne 0x2739
movq 0x38(%rsp), %rdi
callq 0x2190
movq %rax, 0x18(%rsp)
movq 0x48(%rsp), %r14
movl %r14d, 0x20(%rsp)
testl %r14d, %r14d
movq %rbp, %rbx
jle 0x2804
movq 0x10(%rsp), %r12
movq 0x40(%rsp), %rdx
movb -0x1(%rdx,%r13), %cl
movb %cl, (%rax)
incq %rax
decq %r13
jne 0x2797
leaq 0x18(%rsp), %rsi
leaq 0x28(%rsp), %rdx
movq %r15, %rdi
movq %r12, %rcx
callq 0x23ce
testl %r14d, %r14d
jle 0x281e
movl %r14d, %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movl %r14d, %ecx
negl %ecx
xorl %edx, %edx
movq 0x18(%rsp), %rsi
leal (%rcx,%rdx), %edi
addl 0x20(%rsp), %edi
movslq %edi, %rdi
movb (%rsi,%rdi), %dil
movb %dil, (%rsi,%rdx)
incq %rdx
cmpq %rdx, %rax
jne 0x27cf
jmp 0x281e
movq 0x38(%rsp), %rdi
callq 0x2190
movq %rax, 0x18(%rsp)
movl %r14d, 0x20(%rsp)
leaq 0x18(%rsp), %rsi
leaq 0x28(%rsp), %rdx
movq %r15, %rdi
movq 0x10(%rsp), %r12
movq %r12, %rcx
callq 0x23ce
movl %r14d, 0x20(%rsp)
movl 0x30(%rsp), %eax
cmpl $0x2, %eax
jl 0x285f
andl $0x1, %eax
xorl %ecx, %ecx
xorl %edx, %edx
movq 0x28(%rsp), %rsi
leaq (%rsi,%rax), %rdi
movb (%rdi,%rdx,2), %dil
movb %dil, (%rsi,%rdx)
incq %rdx
movslq 0x30(%rsp), %rsi
leaq (%rax,%rcx), %rdi
addq $0x2, %rdi
addq $0x2, %rcx
cmpq %rsi, %rdi
jl 0x2833
movl %esi, %eax
sarl %eax
movl %eax, 0x30(%rsp)
testl %r14d, %r14d
jle 0x29eb
andl $0x7fffffff, %r14d      # imm = 0x7FFFFFFF
xorl %eax, %eax
movq 0x50(%rsp), %rcx
movq (%rcx), %rcx
movslq (%rcx,%rax,4), %rcx
movl 0x8(%rbx), %edx
movl %ecx, %esi
subl %edx, %esi
addl $0x100, %esi            # imm = 0x100
movslq %esi, %rdx
movzbl (%r15,%rdx), %edx
movq 0x18(%rsp), %rdi
movb (%rdi), %r10b
movslq 0x20(%rsp), %r8
cmpq $0x2, %r8
jl 0x28eb
movl $0x1, %r9d
xorl %esi, %esi
testq %rdx, %rdx
je 0x28da
testb %r10b, %r10b
je 0x28da
movzbl %r10b, %esi
movzbl 0x200(%r15,%rsi), %esi
movzbl 0x200(%r15,%rdx), %r10d
addq %rsi, %r10
movb (%r15,%r10), %sil
xorb (%rdi,%r9), %sil
incq %r9
movl %esi, %r10d
cmpq %r9, %r8
jne 0x28b1
jmp 0x28ee
movl %r10d, %esi
testb %sil, %sil
je 0x2906
movzbl %sil, %edi
movzbl 0x200(%r15,%rdi), %edi
movb (%r15,%rdi,2), %dil
jmp 0x2908
xorl %edi, %edi
movq %r14, %r13
movq 0x28(%rsp), %r8
movb (%r8), %bpl
movslq 0x30(%rsp), %r9
cmpq $0x2, %r9
jl 0x2963
movzbl %dil, %r10d
movl $0x1, %r12d
xorl %r11d, %r11d
testb %dil, %dil
je 0x2952
testb %bpl, %bpl
je 0x2952
movzbl %bpl, %r11d
movzbl 0x200(%r15,%r11), %r11d
movzbl 0x200(%r15,%r10), %r14d
addq %r11, %r14
movb (%r15,%r14), %r11b
xorb (%r8,%r12), %r11b
incq %r12
movl %r11d, %ebp
cmpq %r12, %r9
jne 0x2928
jmp 0x2966
movl %ebp, %r11d
movb $-0x1, %dil
testq %rdx, %rdx
je 0x29d0
testb %r11b, %r11b
movq %r13, %r14
movq 0x10(%rsp), %r12
je 0x29d8
movzbl 0x200(%r15,%rdx), %edx
movzbl %r11b, %edi
movzbl 0x200(%r15,%rdi), %edi
addq %rdx, %rdi
movzbl (%r15,%rdi), %edx
cmpq $0x1, %rdx
movl $0x0, %edi
sbbl %edi, %edi
testb %sil, %sil
je 0x29d8
testb %dl, %dl
je 0x29d8
movzbl %sil, %esi
movzbl 0x200(%r15,%rsi), %esi
movzbl 0x200(%r15,%rdx), %edx
subq %rdx, %rsi
movb 0xff(%rsi,%r15), %dil
jmp 0x29d8
movq %r13, %r14
movq 0x10(%rsp), %r12
movq (%rbx), %rdx
xorb %dil, (%rdx,%rcx)
incq %rax
cmpq %r14, %rax
jne 0x2877
movq %r12, %rdi
callq 0x2180
movq 0x40(%rsp), %rdi
callq 0x2180
movq 0x28(%rsp), %rdi
callq 0x2180
movq 0x18(%rsp), %rdi
callq 0x2180
movq %rbx, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq