// File: /workspace/github_c_makefile_star2_O2/cyb70289[P]tt/src/num/mtx-gaussj.c
// Function: tt_mtx_gaussj
int tt_mtx_gaussj(struct tt_mtx *ma, struct tt_mtx *mb)
{
	int ret = 0;
	int i, j;
	int *status_buf;
	int *row_processed, *col_processed;
	int *switchto;

	tt_assert(ma->rows == ma->cols);
	tt_assert(ma->rows == mb->rows);

	/* Alloc memory at once in a larger buffer */
	status_buf = calloc(3 * ma->rows, sizeof(int));
	if (status_buf == NULL)
		return TT_ENOMEM;
	row_processed = status_buf;
	col_processed = row_processed + ma->rows;
	switchto = col_processed + ma->rows;

	for (int row = 0; row < ma->rows; row++) {
		/* Find pivot */
		int rowp = 0, colp = 0;
		double max = 0.0f;
		for (i = 0; i < ma->rows; i++) {
			if (row_processed[i])
				continue;
			for (j = 0; j < ma->cols; j++) {
				if (col_processed[j])
					continue;
				double v = fabs(*_tt_mtx_el(ma, i, j));
				if (v > max) {
					max = v;
					rowp = i;
					colp = j;
				}
			}
		}
		if (_tt_is_zero(max)) {
			ret = TT_NUM_ESINGULAR;	/* Singular matrix */
			goto out;
		}

		/* Pivot is at (rowp, colp). We needn't switch it physically
		 * to (row, row), just identity and eliminate inplace.
		 * Remember the switched orders and restore at the end.
		 */
		switchto[rowp] = colp;

		/* Identity row */
		max = *_tt_mtx_el(ma, rowp, colp);
		_tt_vec_div_sca(_tt_mtx_row(ma, rowp), ma->cols, max);
		_tt_vec_div_sca(_tt_mtx_row(mb, rowp), mb->cols, max);

		/* Eliminate column */
		for (i = 0; i < ma->rows; i++) {
			if (i == rowp)
				continue;

			/* Process coefficient matrix [ma] */
			double *v = _tt_mtx_row(ma, i);
			double *vp = _tt_mtx_row(ma, rowp);
			double _1 = v[colp];
			for (j = 0; j < ma->cols; j++) {
				/* Ignore processed and current column */
				if (col_processed[j] || j == colp)
					continue;
				v[j] -= vp[j] * _1;
			}

			/* Process result matrix [mb] */
			_tt_vec_add_vec_mul_sca(_tt_mtx_row(mb, i),
					_tt_mtx_row(mb, rowp), mb->cols, -_1);
		}

		row_processed[rowp] = col_processed[colp] = 1;
	}

	/* Rows are out of order now. We need to switch them back:
	 * row i should be switch to row switchto[i]
	 */
	for (i = 0; i < mb->rows; i++) {
		j = switchto[i];
		if (i != j) {
			_tt_vec_swap(_tt_mtx_row(mb, i),
					_tt_mtx_row(mb, j), mb->cols);
			__tt_swap(switchto[j], switchto[i]);
		}
	}

out:
	free(status_buf);
	return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl (%rdi), %r14d
cmpl 0x4(%rdi), %r14d
jne 0x18dc
movq %rsi, %rbx
cmpl (%rsi), %r14d
jne 0x18f5
movq %rdi, %r12
movslq %r14d, %r15
leaq (%r15,%r15,2), %rdi
pushq $0x4
popq %rsi
callq 0x10e0
testq %rax, %rax
je 0x182b
movq %rax, %r13
movq %rbx, 0x10(%rsp)
leaq (%rax,%r15,4), %rbx
leaq (%rbx,%r15,4), %rax
movq %rax, 0x8(%rsp)
pushq $-0x65
popq %rax
movq %rax, 0x40(%rsp)
xorl %eax, %eax
movq %r13, 0x18(%rsp)
cmpl %r14d, %eax
jge 0x1833
movl %eax, 0x24(%rsp)
xorpd %xmm0, %xmm0
xorl %r13d, %r13d
xorl %ebp, %ebp
xorl %r15d, %r15d
movslq %r14d, %rax
cmpq %rax, %r13
jge 0x1693
movq 0x18(%rsp), %rax
cmpl $0x0, (%rax,%r13,4)
jne 0x168e
xorl %r14d, %r14d
movslq 0x4(%r12), %rax
cmpq %rax, %r14
jge 0x168a
cmpl $0x0, (%rbx,%r14,4)
jne 0x1685
movq %r12, %rdi
movl %r13d, %esi
movl %r14d, %edx
movsd %xmm0, 0x30(%rsp)
callq 0x191c
movsd (%rax), %xmm0
andpd 0x3cd1(%rip), %xmm0     # 0x5340
movsd 0x30(%rsp), %xmm1
ucomisd %xmm1, %xmm0
cmoval %r13d, %ebp
cmoval %r14d, %r15d
maxsd %xmm1, %xmm0
incq %r14
jmp 0x163e
movl (%r12), %r14d
incq %r13
jmp 0x1627
ucomisd 0x3cc5(%rip), %xmm0     # 0x5360
jne 0x16a3
jnp 0x18bb
movslq %ebp, %r13
movq 0x8(%rsp), %rax
movl %r15d, (%rax,%r13,4)
movq %r12, %rdi
movl %r13d, %esi
movl %r15d, %edx
callq 0x191c
movsd (%rax), %xmm0
movsd %xmm0, 0x30(%rsp)
movq %r12, %rdi
movl %r13d, %esi
callq 0x19dd
movl 0x4(%r12), %esi
movq %rax, %rdi
movsd 0x30(%rsp), %xmm0
callq 0x197e
movq 0x10(%rsp), %r14
movq %r14, %rdi
movq %r13, 0x50(%rsp)
movl %r13d, %esi
callq 0x19dd
movl 0x4(%r14), %esi
movq %rax, %rdi
movsd 0x30(%rsp), %xmm0
callq 0x197e
movslq %r15d, %rcx
movq %rcx, 0x48(%rsp)
movl %ecx, %r13d
xorl %esi, %esi
movl %ebp, 0x28(%rsp)
movl (%r12), %r14d
cmpl %r14d, %esi
jge 0x1806
cmpl %ebp, %esi
jne 0x1732
incl %esi
jmp 0x171d
movq %r12, %rdi
movl %ebp, %r15d
movl %esi, %ebp
callq 0x19dd
movq %rax, %r14
movq %r12, %rdi
movl %r15d, %esi
callq 0x19dd
movq 0x48(%rsp), %rcx
movsd (%r14,%rcx,8), %xmm2
movl 0x4(%r12), %ecx
testl %ecx, %ecx
movl $0x0, %edx
cmovlel %edx, %ecx
xorl %edx, %edx
cmpq %rdx, %rcx
je 0x1797
cmpl $0x0, (%rbx,%rdx,4)
jne 0x1792
cmpq %rdx, %r13
je 0x1792
movsd (%r14,%rdx,8), %xmm0
movsd (%rax,%rdx,8), %xmm1
mulsd %xmm2, %xmm1
subsd %xmm1, %xmm0
movsd %xmm0, (%r14,%rdx,8)
incq %rdx
jmp 0x1769
movq 0x10(%rsp), %r15
movq %r15, %rdi
movl %ebp, %esi
movl %ebp, 0x2c(%rsp)
movapd %xmm2, 0x30(%rsp)
callq 0x19dd
movq %rax, %r14
movq %r15, %rdi
movl 0x28(%rsp), %ebp
movl %ebp, %esi
callq 0x19dd
movapd 0x30(%rsp), %xmm1
movl 0x2c(%rsp), %esi
movl 0x4(%r15), %ecx
xorpd 0x3b59(%rip), %xmm1     # 0x5330
testl %ecx, %ecx
movl $0x0, %edx
cmovlel %edx, %ecx
xorl %edx, %edx
cmpq %rdx, %rcx
je 0x172e
movsd (%rax,%rdx,8), %xmm0
mulsd %xmm1, %xmm0
addsd (%r14,%rdx,8), %xmm0
movsd %xmm0, (%r14,%rdx,8)
incq %rdx
jmp 0x17e3
pushq $0x1
popq %rax
movq 0x48(%rsp), %rcx
movl %eax, (%rbx,%rcx,4)
movq 0x18(%rsp), %r13
movq 0x50(%rsp), %rcx
movl %eax, (%r13,%rcx,4)
movl 0x24(%rsp), %eax
incl %eax
jmp 0x160e
pushq $-0x1
popq %rax
jmp 0x18cd
movq $0x0, 0x40(%rsp)
xorl %r15d, %r15d
movq 0x10(%rsp), %rbx
movslq (%rbx), %rax
cmpq %rax, %r15
jge 0x18c0
movq 0x8(%rsp), %rax
movl (%rax,%r15,4), %eax
cmpq %rax, %r15
je 0x18b6
movslq %eax, %r14
movq %rbx, %rdi
movl %r15d, %esi
callq 0x19dd
movq %rax, %r12
movq %rbx, %rdi
movl %r14d, %esi
callq 0x19dd
movl 0x4(%rbx), %ecx
testl %ecx, %ecx
movl $0x0, %edx
cmovlel %edx, %ecx
xorl %edx, %edx
cmpq %rdx, %rcx
je 0x18a5
movsd (%r12,%rdx,8), %xmm0
movsd (%rax,%rdx,8), %xmm1
movsd %xmm1, (%r12,%rdx,8)
movsd %xmm0, (%rax,%rdx,8)
incq %rdx
jmp 0x1885
movq 0x8(%rsp), %rcx
movl (%rcx,%r14,4), %eax
movl %r14d, (%rcx,%r14,4)
movl %eax, (%rcx,%r15,4)
incq %r15
jmp 0x1844
movq 0x18(%rsp), %r13
movq %r13, %rdi
callq 0x1030
movq 0x40(%rsp), %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x38ea(%rip), %rsi      # 0x51cd
leaq 0x38a2(%rip), %rdx      # 0x518c
leaq 0x38ea(%rip), %rcx      # 0x51db
pushq $0x1b
jmp 0x190c
leaq 0x38d1(%rip), %rsi      # 0x51cd
leaq 0x3889(%rip), %rdx      # 0x518c
leaq 0x38d1(%rip), %rcx      # 0x51db
pushq $0x1c
popq %r8
xorl %edi, %edi
xorl %eax, %eax
callq 0x258c
callq 0x1050