// File: /workspace/github_c_makefile_star2_O3/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 $0x38, %rsp
movl (%rdi), %ebp
cmpl 0x4(%rdi), %ebp
jne 0x1d99
cmpl (%rsi), %ebp
jne 0x1d9e
movq %rdi, %r15
movq %rsi, 0x8(%rsp)
movslq %ebp, %rbx
leaq (%rbx,%rbx,2), %rdi
movl $0x4, %esi
callq 0x10e0
testq %rax, %rax
je 0x1d62
testl %ebp, %ebp
jle 0x1d50
leaq (%rax,%rbx,4), %r13
leaq (,%rbx,4), %r14
addq %r13, %r14
movapd 0x3942(%rip), %xmm3     # 0x5330
xorpd %xmm4, %xmm4
movapd 0x3946(%rip), %xmm5     # 0x5340
xorl %ecx, %ecx
movq %rax, 0x28(%rsp)
movq %r14, 0x20(%rsp)
movl $0xffffff9b, %r11d      # imm = 0xFFFFFF9B
testl %ebp, %ebp
jle 0x1d53
movl %ecx, 0x4(%rsp)
movl %ebp, %r10d
xorl %ecx, %ecx
xorpd %xmm0, %xmm0
xorl %edx, %edx
xorl %ebx, %ebx
xorl %r12d, %r12d
cmpl $0x0, (%rax,%rdx,4)
jne 0x1a76
movslq 0x4(%r15), %rsi
testq %rsi, %rsi
jle 0x1a76
movq %rcx, %rdi
imulq %rsi, %rdi
xorl %r8d, %r8d
cmpl $0x0, (%r13,%r8,4)
jne 0x1a6e
movq 0x8(%r15), %r9
addq %rdi, %r9
movsd (%r9,%r8,8), %xmm1
andpd %xmm3, %xmm1
ucomisd %xmm0, %xmm1
cmoval %edx, %r12d
cmoval %r8d, %ebx
maxsd %xmm0, %xmm1
movapd %xmm1, %xmm0
incq %r8
cmpq %r8, %rsi
jne 0x1a41
incq %rdx
addq $0x8, %rcx
cmpq %r10, %rdx
jne 0x1a28
ucomisd %xmm4, %xmm0
jne 0x1a8e
jnp 0x1d53
movslq %r12d, %rcx
movl %ebx, (%r14,%rcx,4)
cmpl %ecx, %ebp
jle 0x1d85
movl 0x4(%r15), %ebp
cmpl %ebx, %ebp
jle 0x1d8a
movq %rcx, 0x30(%rsp)
movl %ebp, %eax
imull %r12d, %eax
movslq %eax, %r14
shlq $0x3, %r14
addq 0x8(%r15), %r14
movslq %ebx, %r11
movsd (%r14,%r11,8), %xmm1
ucomisd %xmm4, %xmm1
movq %r11, 0x18(%rsp)
movsd %xmm1, 0x10(%rsp)
jne 0x1b11
jp 0x1b11
xorl %edi, %edi
leaq 0x370c(%rip), %rsi      # 0x51f0
leaq 0x3715(%rip), %rdx      # 0x5200
xorl %eax, %eax
callq 0x290e
movsd 0x10(%rsp), %xmm1
movq 0x18(%rsp), %r11
movapd 0x383b(%rip), %xmm5     # 0x5340
xorpd %xmm4, %xmm4
movapd 0x381f(%rip), %xmm3     # 0x5330
testl %ebp, %ebp
jle 0x1b2f
xorl %eax, %eax
movsd (%r14,%rax,8), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%r14,%rax,8)
incq %rax
cmpq %rax, %rbp
jne 0x1b17
movq 0x8(%rsp), %r10
cmpl %r12d, (%r10)
jle 0x1d8f
movl 0x4(%r10), %ebp
movl %ebp, %eax
imull %r12d, %eax
movslq %eax, %r14
shlq $0x3, %r14
addq 0x8(%r10), %r14
ucomisd %xmm4, %xmm1
jne 0x1b95
jp 0x1b95
xorl %edi, %edi
leaq 0x368d(%rip), %rsi      # 0x51f0
leaq 0x3696(%rip), %rdx      # 0x5200
xorl %eax, %eax
callq 0x290e
movsd 0x10(%rsp), %xmm1
movq 0x18(%rsp), %r11
movapd 0x37bc(%rip), %xmm5     # 0x5340
xorpd %xmm4, %xmm4
movapd 0x37a0(%rip), %xmm3     # 0x5330
movq 0x8(%rsp), %r10
testl %ebp, %ebp
jle 0x1bb3
xorl %eax, %eax
movsd (%r14,%rax,8), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%r14,%rax,8)
incq %rax
cmpq %rax, %rbp
jne 0x1b9b
movl (%r15), %ebp
testl %ebp, %ebp
movq 0x28(%rsp), %rax
movq 0x20(%rsp), %r14
jle 0x1cb4
movl %ebx, %r9d
xorl %ecx, %ecx
cmpl %r12d, %ecx
je 0x1caa
cmpl %r12d, %ebp
jle 0x1d76
movl 0x4(%r15), %edx
movl %edx, %esi
imull %ecx, %esi
movq 0x8(%r15), %rdi
movslq %esi, %rsi
leaq (%rdi,%rsi,8), %rsi
movsd (%rsi,%r11,8), %xmm0
testl %edx, %edx
jle 0x1c4a
movl %edx, %esi
imull %r12d, %esi
movslq %esi, %rsi
leaq (%rdi,%rsi,8), %rsi
movl %edx, %r8d
imull %ecx, %r8d
movslq %r8d, %r8
leaq (%rdi,%r8,8), %rdi
xorl %r8d, %r8d
cmpl $0x0, (%r13,%r8,4)
jne 0x1c42
cmpq %r8, %r9
je 0x1c42
movsd (%rdi,%r8,8), %xmm1
movsd (%rsi,%r8,8), %xmm2
mulsd %xmm0, %xmm2
subsd %xmm2, %xmm1
movsd %xmm1, (%rdi,%r8,8)
incq %r8
cmpq %r8, %rdx
jne 0x1c1b
movl (%r10), %edx
cmpl %ecx, %edx
jle 0x1d7b
cmpl %r12d, %edx
jle 0x1d80
movl 0x4(%r10), %edx
testl %edx, %edx
jle 0x1caa
movq 0x8(%r10), %rdi
movl %edx, %esi
imull %r12d, %esi
movslq %esi, %rsi
leaq (%rdi,%rsi,8), %rsi
xorpd %xmm5, %xmm0
movl %edx, %r8d
imull %ecx, %r8d
movslq %r8d, %r8
leaq (%rdi,%r8,8), %rdi
xorl %r8d, %r8d
movsd (%rsi,%r8,8), %xmm1
mulsd %xmm0, %xmm1
addsd (%rdi,%r8,8), %xmm1
movsd %xmm1, (%rdi,%r8,8)
incq %r8
cmpq %r8, %rdx
jne 0x1c8c
incl %ecx
cmpl %ebp, %ecx
jne 0x1bcd
movl $0x1, %ecx
movl %ecx, (%r13,%r11,4)
movq 0x30(%rsp), %rdx
movl %ecx, (%rax,%rdx,4)
movl 0x4(%rsp), %ecx
incl %ecx
cmpl %ebp, %ecx
jl 0x1a06
movslq (%r10), %r11
testq %r11, %r11
jle 0x1d50
xorl %ecx, %ecx
movl (%r14,%rcx,4), %edx
cmpq %rdx, %rcx
je 0x1d48
cmpl %edx, %r11d
jle 0x1d94
movl 0x4(%r10), %esi
testl %esi, %esi
jle 0x1d39
movq 0x8(%r10), %r8
movl %esi, %edi
imull %edx, %edi
movslq %edi, %rdi
leaq (%r8,%rdi,8), %rdi
movl %esi, %r9d
imull %ecx, %r9d
movslq %r9d, %r9
leaq (%r8,%r9,8), %r8
xorl %r9d, %r9d
movsd (%r8,%r9,8), %xmm0
movsd (%rdi,%r9,8), %xmm1
movsd %xmm1, (%r8,%r9,8)
movsd %xmm0, (%rdi,%r9,8)
incq %r9
cmpq %r9, %rsi
jne 0x1d19
movslq %edx, %rsi
movl (%r14,%rsi,4), %edi
movl %edx, (%r14,%rsi,4)
movl %edi, (%r14,%rcx,4)
incq %rcx
cmpq %r11, %rcx
jne 0x1cde
xorl %r11d, %r11d
movq %rax, %rdi
movl %r11d, %ebx
callq 0x1030
movl %ebx, %eax
jmp 0x1d67
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x1338
callq 0x1360
callq 0x1388
callq 0x12c0
callq 0x12e8
callq 0x1310
callq 0x13b0
callq 0x1270
callq 0x1298
nop