// File: syzcch[P]FEC_C_version/./fec_rs.h
// Function: rscode::gf_invert_matrix(int*, int)
int *gf_invert_matrix(int *mat, int rows)
    {
        int *inv;
        int *copy;
        int cols, i, j, k, x, rs2;
        int row_start, tmp, inverse;

        cols = rows;

        inv = (int *) malloc(sizeof(int)*rows*cols);
        if (inv == NULL)
        {
            printf("gf_invert_matrix - inv");
        }
        copy = (int *) malloc(sizeof(int)*rows*cols);
        if (copy == NULL)
        {
            printf("gf_invert_matrix - copy");
        }

        k = 0;
        for (i = 0; i < rows; i++)
        {
            for (j = 0; j < cols; j++)
            {
                inv[k] = (i == j) ? 1 : 0;
                copy[k] = mat[k];
                k++;
            }
        }

        /* First -- convert into upper triangular */
        for (i = 0; i < cols; i++)
        {
            row_start = cols*i;

            /* Swap rows if we ave a zero i,i element.  If we can't swap, then the
            matrix was not invertible */

            if (copy[row_start+i] == 0)
            {
                for (j = i+1; j < rows && copy[cols*j+i] == 0; j++) ;
                if (j == rows)
                {
                    printf( "gf_invert_matrix: Matrix not invertible!!\n");
                    exit(1);
                }
                rs2 = j*cols;
                for (k = 0; k < cols; k++)
                {
                    tmp = copy[row_start+k];
                    copy[row_start+k] = copy[rs2+k];
                    copy[rs2+k] = tmp;
                    tmp = inv[row_start+k];
                    inv[row_start+k] = inv[rs2+k];
                    inv[rs2+k] = tmp;
                }
            }

            /* Multiply the row by 1/element i,i */
            tmp = copy[row_start+i];
            if (tmp != 1)
            {
                inverse = gf_single_divide(1, tmp);
                for (j = 0; j < cols; j++)
                {
                    copy[row_start+j] = gf_single_multiply(copy[row_start+j], inverse);
                    inv[row_start+j] = gf_single_multiply(inv[row_start+j], inverse);
                }
                /* pic(inv, copy, rows, "Divided through"); */
            }

            /* Now for each j>i, add A_ji*Ai to Aj */
            k = row_start+i;
            for (j = i+1; j != cols; j++)
            {
                k += cols;
                if (copy[k] != 0)
                {
                    if (copy[k] == 1)
                    {
                        rs2 = cols*j;
                        for (x = 0; x < cols; x++)
                        {
                            copy[rs2+x] ^= copy[row_start+x];
                            inv[rs2+x] ^= inv[row_start+x];
                        }
                    }
                    else
                    {
                        tmp = copy[k];
                        rs2 = cols*j;
                        for (x = 0; x < cols; x++)
                        {
                            copy[rs2+x] ^= gf_single_multiply(tmp, copy[row_start+x]);
                            inv[rs2+x] ^= gf_single_multiply(tmp, inv[row_start+x]);
                        }
                    }
                }
            }
            /* pic(inv, copy, rows, "Eliminated rows"); */
        }

        /* Now the matrix is upper triangular.  Start at the top and multiply down */

        for (i = rows-1; i >= 0; i--)
        {
            row_start = i*cols;
            for (j = 0; j < i; j++)
            {
                rs2 = j*cols;
                if (0 != copy[rs2+i])
                {
                    tmp = copy[rs2+i];
                    copy[rs2+i] = 0;
                    for (k = 0; k < cols; k++)
                    {
                        inv[rs2+k] ^= gf_single_multiply(tmp, inv[row_start+k]);
                    }
                }
            }
            /* pic(inv, copy, rows, "One Column"); */
        }
        free(copy);
        return inv;
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x58(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x2c(%rbp)
movslq -0x14(%rbp), %rdi
shlq $0x2, %rdi
movslq -0x2c(%rbp), %rax
imulq %rax, %rdi
callq 0x2190
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x424f
leaq 0x107b(%rip), %rdi      # 0x52c3
movb $0x0, %al
callq 0x2040
movslq -0x14(%rbp), %rdi
shlq $0x2, %rdi
movslq -0x2c(%rbp), %rax
imulq %rax, %rdi
callq 0x2190
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x427d
leaq 0x1064(%rip), %rdi      # 0x52da
movb $0x0, %al
callq 0x2040
movl $0x0, -0x38(%rbp)
movl $0x0, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x14(%rbp), %eax
jge 0x42f6
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x42e9
movl -0x30(%rbp), %ecx
movl -0x34(%rbp), %esi
xorl %edx, %edx
movl $0x1, %eax
cmpl %esi, %ecx
cmovel %eax, %edx
movq -0x20(%rbp), %rax
movslq -0x38(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x10(%rbp), %rax
movslq -0x38(%rbp), %rcx
movl (%rax,%rcx,4), %edx
movq -0x28(%rbp), %rax
movslq -0x38(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x429a
jmp 0x42eb
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x428b
movl $0x0, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x4661
movl -0x2c(%rbp), %eax
imull -0x30(%rbp), %eax
movl %eax, -0x44(%rbp)
movq -0x28(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x30(%rbp), %ecx
movslq %ecx, %rcx
cmpl $0x0, (%rax,%rcx,4)
jne 0x444a
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %ecx
xorl %eax, %eax
cmpl -0x14(%rbp), %ecx
movb %al, -0x59(%rbp)
jge 0x435b
movq -0x28(%rbp), %rax
movl -0x2c(%rbp), %ecx
imull -0x34(%rbp), %ecx
addl -0x30(%rbp), %ecx
movslq %ecx, %rcx
cmpl $0x0, (%rax,%rcx,4)
sete %al
movb %al, -0x59(%rbp)
movb -0x59(%rbp), %al
testb $0x1, %al
jne 0x4364
jmp 0x4371
jmp 0x4366
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x4333
movl -0x34(%rbp), %eax
cmpl -0x14(%rbp), %eax
jne 0x4391
leaq 0xf72(%rip), %rdi       # 0x52f2
movb $0x0, %al
callq 0x2040
movl $0x1, %edi
callq 0x2170
movl -0x34(%rbp), %eax
imull -0x2c(%rbp), %eax
movl %eax, -0x40(%rbp)
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x4448
movq -0x28(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x38(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x48(%rbp)
movq -0x28(%rbp), %rax
movl -0x40(%rbp), %ecx
addl -0x38(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
movq -0x28(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x38(%rbp), %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl -0x48(%rbp), %edx
movq -0x28(%rbp), %rax
movl -0x40(%rbp), %ecx
addl -0x38(%rbp), %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movq -0x20(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x38(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x48(%rbp)
movq -0x20(%rbp), %rax
movl -0x40(%rbp), %ecx
addl -0x38(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
movq -0x20(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x38(%rbp), %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl -0x48(%rbp), %edx
movq -0x20(%rbp), %rax
movl -0x40(%rbp), %ecx
addl -0x38(%rbp), %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x43a2
jmp 0x444a
movq -0x28(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x30(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x48(%rbp)
cmpl $0x1, -0x48(%rbp)
je 0x44f3
movq -0x58(%rbp), %rdi
movl -0x48(%rbp), %edx
movl $0x1, %esi
callq 0x3840
movl %eax, -0x4c(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x44f1
movq -0x58(%rbp), %rdi
movq -0x28(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x34(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %esi
movl -0x4c(%rbp), %edx
callq 0x3c60
movq -0x58(%rbp), %rdi
movl %eax, %edx
movq -0x28(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x34(%rbp), %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movq -0x20(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x34(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %esi
movl -0x4c(%rbp), %edx
callq 0x3c60
movl %eax, %edx
movq -0x20(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x34(%rbp), %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x4482
jmp 0x44f3
movl -0x44(%rbp), %eax
addl -0x30(%rbp), %eax
movl %eax, -0x38(%rbp)
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x2c(%rbp), %eax
je 0x4651
movl -0x2c(%rbp), %eax
addl -0x38(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0x28(%rbp), %rax
movslq -0x38(%rbp), %rcx
cmpl $0x0, (%rax,%rcx,4)
je 0x4641
movq -0x28(%rbp), %rax
movslq -0x38(%rbp), %rcx
cmpl $0x1, (%rax,%rcx,4)
jne 0x45a9
movl -0x2c(%rbp), %eax
imull -0x34(%rbp), %eax
movl %eax, -0x40(%rbp)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x45a4
movq -0x28(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x3c(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
movq -0x28(%rbp), %rax
movl -0x40(%rbp), %ecx
addl -0x3c(%rbp), %ecx
movslq %ecx, %rcx
xorl (%rax,%rcx,4), %edx
movl %edx, (%rax,%rcx,4)
movq -0x20(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x3c(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
movq -0x20(%rbp), %rax
movl -0x40(%rbp), %ecx
addl -0x3c(%rbp), %ecx
movslq %ecx, %rcx
xorl (%rax,%rcx,4), %edx
movl %edx, (%rax,%rcx,4)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x454b
jmp 0x463f
movq -0x28(%rbp), %rax
movslq -0x38(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x48(%rbp)
movl -0x2c(%rbp), %eax
imull -0x34(%rbp), %eax
movl %eax, -0x40(%rbp)
movl $0x0, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x463d
movq -0x58(%rbp), %rdi
movl -0x48(%rbp), %esi
movq -0x28(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x3c(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
callq 0x3c60
movq -0x58(%rbp), %rdi
movl %eax, %edx
movq -0x28(%rbp), %rax
movl -0x40(%rbp), %ecx
addl -0x3c(%rbp), %ecx
movslq %ecx, %rcx
xorl (%rax,%rcx,4), %edx
movl %edx, (%rax,%rcx,4)
movl -0x48(%rbp), %esi
movq -0x20(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x3c(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
callq 0x3c60
movl %eax, %edx
movq -0x20(%rbp), %rax
movl -0x40(%rbp), %ecx
addl -0x3c(%rbp), %ecx
movslq %ecx, %rcx
xorl (%rax,%rcx,4), %edx
movl %edx, (%rax,%rcx,4)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x45c8
jmp 0x463f
jmp 0x4641
jmp 0x4643
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x4505
jmp 0x4653
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x42fd
movl -0x14(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x30(%rbp)
cmpl $0x0, -0x30(%rbp)
jl 0x4743
movl -0x30(%rbp), %eax
imull -0x2c(%rbp), %eax
movl %eax, -0x44(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x30(%rbp), %eax
jge 0x4733
movl -0x34(%rbp), %eax
imull -0x2c(%rbp), %eax
movl %eax, -0x40(%rbp)
movq -0x28(%rbp), %rcx
movl -0x40(%rbp), %eax
addl -0x30(%rbp), %eax
movslq %eax, %rdx
xorl %eax, %eax
cmpl (%rcx,%rdx,4), %eax
je 0x4723
movq -0x28(%rbp), %rax
movl -0x40(%rbp), %ecx
addl -0x30(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x48(%rbp)
movq -0x28(%rbp), %rax
movl -0x40(%rbp), %ecx
addl -0x30(%rbp), %ecx
movslq %ecx, %rcx
movl $0x0, (%rax,%rcx,4)
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x4721
movq -0x58(%rbp), %rdi
movl -0x48(%rbp), %esi
movq -0x20(%rbp), %rax
movl -0x44(%rbp), %ecx
addl -0x38(%rbp), %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
callq 0x3c60
movl %eax, %edx
movq -0x20(%rbp), %rax
movl -0x40(%rbp), %ecx
addl -0x38(%rbp), %ecx
movslq %ecx, %rcx
xorl (%rax,%rcx,4), %edx
movl %edx, (%rax,%rcx,4)
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x46dd
jmp 0x4723
jmp 0x4725
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x4685
jmp 0x4735
movl -0x30(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x466a
movq -0x28(%rbp), %rdi
callq 0x2160
movq -0x20(%rbp), %rax
addq $0x60, %rsp
popq %rbp
retq