// File: /workspace/github_c_makefile_star2_O1/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 $0x48, %rsp
movslq (%rdi), %rbx
cmpl 0x4(%rdi), %ebx
jne 0x1e01
cmpl (%rsi), %ebx
jne 0x1e06
movq %rdi, %r15
movq %rsi, 0x8(%rsp)
leaq (%rbx,%rbx,2), %rdi
movl $0x4, %esi
callq 0x10e0
testq %rax, %rax
je 0x1d1b
leaq (%rax,%rbx,4), %r13
leaq (,%rbx,4), %r14
addq %r13, %r14
movl (%r15), %ebx
testl %ebx, %ebx
jle 0x1d25
movapd 0x3921(%rip), %xmm3     # 0x5330
xorpd %xmm4, %xmm4
movl $0x0, 0x4(%rsp)
xorl %edx, %edx
movq 0x8(%rsp), %r11
movq %rax, 0x28(%rsp)
movq %r14, 0x20(%rsp)
movl %edx, 0x14(%rsp)
testl %ebx, %ebx
jle 0x1aac
movl %ebx, %ecx
xorl %edx, %edx
xorpd %xmm0, %xmm0
xorl %esi, %esi
xorl %ebp, %ebp
xorl %r12d, %r12d
cmpl $0x0, (%rax,%rsi,4)
jne 0x1a91
movslq 0x4(%r15), %rdi
testq %rdi, %rdi
jle 0x1a91
movq %rdx, %r8
imulq %rdi, %r8
xorl %r9d, %r9d
cmpl $0x0, (%r13,%r9,4)
jne 0x1a89
movq 0x8(%r15), %r10
addq %r8, %r10
movsd (%r10,%r9,8), %xmm1
andpd %xmm3, %xmm1
ucomisd %xmm0, %xmm1
cmoval %esi, %r12d
cmoval %r9d, %ebp
maxsd %xmm0, %xmm1
movapd %xmm1, %xmm0
incq %r9
cmpq %r9, %rdi
jne 0x1a5c
incq %rsi
addq $0x8, %rdx
cmpq %rcx, %rsi
jne 0x1a43
cmpeqsd %xmm4, %xmm0
movq %xmm0, %rdx
andl $0x1, %edx
jmp 0x1ab3
movb $0x1, %dl
xorl %r12d, %r12d
xorl %ebp, %ebp
testb %dl, %dl
je 0x1ac9
movl $0xffffff9b, 0x4(%rsp)  # imm = 0xFFFFFF9B
movl $0xf, %ecx
jmp 0x1d00
movslq %r12d, %rcx
movl %ebp, (%r14,%rcx,4)
movq %rcx, 0x38(%rsp)
cmpl %ecx, %ebx
jle 0x1ded
movl 0x4(%r15), %ebx
cmpl %ebp, %ebx
jle 0x1df2
movl %ebx, %eax
imull %r12d, %eax
movslq %eax, %r14
shlq $0x3, %r14
addq 0x8(%r15), %r14
movslq %ebp, %rax
movq %rax, 0x40(%rsp)
movsd (%r14,%rax,8), %xmm1
ucomisd %xmm4, %xmm1
movq %rdx, 0x30(%rsp)
movsd %xmm1, 0x18(%rsp)
jne 0x1b49
jp 0x1b49
xorl %edi, %edi
leaq 0x36cc(%rip), %rsi      # 0x51f0
leaq 0x36d5(%rip), %rdx      # 0x5200
xorl %eax, %eax
callq 0x296e
movsd 0x18(%rsp), %xmm1
xorpd %xmm4, %xmm4
movapd 0x37ec(%rip), %xmm3     # 0x5330
movq 0x8(%rsp), %r11
testl %ebx, %ebx
jle 0x1b67
xorl %eax, %eax
movsd (%r14,%rax,8), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%r14,%rax,8)
incq %rax
cmpq %rax, %rbx
jne 0x1b4f
cmpl %r12d, (%r11)
jle 0x1df7
movl 0x4(%r11), %ebx
movl %ebx, %eax
imull %r12d, %eax
movslq %eax, %r14
shlq $0x3, %r14
addq 0x8(%r11), %r14
ucomisd %xmm4, %xmm1
jne 0x1bbb
jp 0x1bbb
xorl %edi, %edi
leaq 0x365a(%rip), %rsi      # 0x51f0
leaq 0x3663(%rip), %rdx      # 0x5200
xorl %eax, %eax
callq 0x296e
movsd 0x18(%rsp), %xmm1
xorpd %xmm4, %xmm4
movapd 0x377a(%rip), %xmm3     # 0x5330
movq 0x8(%rsp), %r11
testl %ebx, %ebx
jle 0x1bd9
xorl %eax, %eax
movsd (%r14,%rax,8), %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, (%r14,%rax,8)
incq %rax
cmpq %rax, %rbx
jne 0x1bc1
movl (%r15), %r10d
testl %r10d, %r10d
movq 0x28(%rsp), %rax
movq 0x20(%rsp), %r14
movapd 0x374f(%rip), %xmm5     # 0x5340
movq 0x40(%rsp), %rbx
jle 0x1ce7
movl %ebp, %ecx
xorl %edx, %edx
cmpl %r12d, %edx
je 0x1cdc
cmpl %r12d, %r10d
jle 0x1dde
movl 0x4(%r15), %esi
movl %esi, %edi
imull %edx, %edi
movq 0x8(%r15), %r8
movslq %edi, %rdi
leaq (%r8,%rdi,8), %rdi
movsd (%rdi,%rbx,8), %xmm0
testl %esi, %esi
jle 0x1c7c
movl %esi, %edi
imull %r12d, %edi
movslq %edi, %rdi
leaq (%r8,%rdi,8), %rdi
movl %esi, %r9d
imull %edx, %r9d
movslq %r9d, %r9
leaq (%r8,%r9,8), %r8
xorl %r9d, %r9d
cmpl $0x0, (%r13,%r9,4)
jne 0x1c74
cmpq %r9, %rcx
je 0x1c74
movsd (%r8,%r9,8), %xmm1
movsd (%rdi,%r9,8), %xmm2
mulsd %xmm0, %xmm2
subsd %xmm2, %xmm1
movsd %xmm1, (%r8,%r9,8)
incq %r9
cmpq %r9, %rsi
jne 0x1c4d
movl (%r11), %esi
cmpl %edx, %esi
jle 0x1de3
cmpl %r12d, %esi
jle 0x1de8
movl 0x4(%r11), %esi
testl %esi, %esi
jle 0x1cdc
movq 0x8(%r11), %r8
movl %esi, %edi
imull %r12d, %edi
movslq %edi, %rdi
leaq (%r8,%rdi,8), %rdi
xorpd %xmm5, %xmm0
movl %esi, %r9d
imull %edx, %r9d
movslq %r9d, %r9
leaq (%r8,%r9,8), %r8
xorl %r9d, %r9d
movsd (%rdi,%r9,8), %xmm1
mulsd %xmm0, %xmm1
addsd (%r8,%r9,8), %xmm1
movsd %xmm1, (%r8,%r9,8)
incq %r9
cmpq %r9, %rsi
jne 0x1cbe
incl %edx
cmpl %r10d, %edx
jne 0x1c00
movl $0x1, %ecx
movl %ecx, (%r13,%rbx,4)
movq 0x38(%rsp), %rdx
movl %ecx, (%rax,%rdx,4)
xorl %ecx, %ecx
movq 0x30(%rsp), %rdx
testb %dl, %dl
movl 0x14(%rsp), %edx
jne 0x1d33
incl %edx
movl (%r15), %ebx
cmpl %ebx, %edx
jl 0x1a2c
movl 0x4(%rsp), %ebx
jmp 0x1d2c
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0x1dcd
xorl %ebx, %ebx
movq 0x8(%rsp), %r11
movl $0x6, %ecx
jmp 0x1d37
movl 0x4(%rsp), %ebx
cmpl $0xf, %ecx
je 0x1dc5
cmpl $0x6, %ecx
jne 0x1dcd
movslq (%r11), %r10
testq %r10, %r10
jle 0x1dc5
xorl %ecx, %ecx
movl (%r14,%rcx,4), %edx
cmpq %rdx, %rcx
je 0x1dbd
cmpl %edx, %r10d
jle 0x1dfc
movl 0x4(%r11), %esi
testl %esi, %esi
jle 0x1dae
movq 0x8(%r11), %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 0x1d8e
movslq %edx, %rsi
movl (%r14,%rsi,4), %edi
movl %edx, (%r14,%rsi,4)
movl %edi, (%r14,%rcx,4)
incq %rcx
cmpq %r10, %rcx
jne 0x1d53
movq %rax, %rdi
callq 0x1030
movl %ebx, %eax
addq $0x48, %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