// File: /workspace/github_c_makefile_star2_O0/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:
subq $0x98, %rsp
movq %rdi, 0x88(%rsp)
movq %rsi, 0x80(%rsp)
movl $0x0, 0x7c(%rsp)
movq 0x88(%rsp), %rax
movl (%rax), %eax
movq 0x88(%rsp), %rcx
cmpl 0x4(%rcx), %eax
sete %al
xorb $-0x1, %al
xorb $-0x1, %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
cltq
cmpq $0x0, %rax
je 0x18f3
xorl %edi, %edi
leaq 0x6906(%rip), %rsi      # 0x81d9
leaq 0x68b2(%rip), %rdx      # 0x818c
leaq 0x6906(%rip), %rcx      # 0x81e7
movl $0x1b, %r8d
movb $0x0, %al
callq 0x3600
callq 0x1040
jmp 0x18f5
jmp 0x18f7
movq 0x88(%rsp), %rax
movl (%rax), %eax
movq 0x80(%rsp), %rcx
cmpl (%rcx), %eax
sete %al
xorb $-0x1, %al
xorb $-0x1, %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
cltq
cmpq $0x0, %rax
je 0x194a
xorl %edi, %edi
leaq 0x68af(%rip), %rsi      # 0x81d9
leaq 0x685b(%rip), %rdx      # 0x818c
leaq 0x68af(%rip), %rcx      # 0x81e7
movl $0x1c, %r8d
movb $0x0, %al
callq 0x3600
callq 0x1040
jmp 0x194c
movq 0x88(%rsp), %rax
imull $0x3, (%rax), %eax
movslq %eax, %rdi
movl $0x4, %esi
callq 0x10e0
movq %rax, 0x68(%rsp)
cmpq $0x0, 0x68(%rsp)
jne 0x1981
movl $0xffffffff, 0x94(%rsp) # imm = 0xFFFFFFFF
jmp 0x1de0
movq 0x68(%rsp), %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
movq 0x88(%rsp), %rcx
movslq (%rcx), %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x58(%rsp)
movq 0x58(%rsp), %rax
movq 0x88(%rsp), %rcx
movslq (%rcx), %rcx
shlq $0x2, %rcx
addq %rcx, %rax
movq %rax, 0x50(%rsp)
movl $0x0, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
movq 0x88(%rsp), %rcx
cmpl (%rcx), %eax
jge 0x1d05
movl $0x0, 0x48(%rsp)
movl $0x0, 0x44(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x38(%rsp)
movl $0x0, 0x78(%rsp)
movl 0x78(%rsp), %eax
movq 0x88(%rsp), %rcx
cmpl (%rcx), %eax
jge 0x1acc
movq 0x60(%rsp), %rax
movslq 0x78(%rsp), %rcx
cmpl $0x0, (%rax,%rcx,4)
je 0x1a29
jmp 0x1abc
movl $0x0, 0x74(%rsp)
movl 0x74(%rsp), %eax
movq 0x88(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jge 0x1aba
movq 0x58(%rsp), %rax
movslq 0x74(%rsp), %rcx
cmpl $0x0, (%rax,%rcx,4)
je 0x1a54
jmp 0x1aaa
movq 0x88(%rsp), %rdi
movl 0x78(%rsp), %esi
movl 0x74(%rsp), %edx
callq 0x1df0
movsd (%rax), %xmm0
movaps 0x68bc(%rip), %xmm1     # 0x8330
pand %xmm1, %xmm0
movsd %xmm0, 0x30(%rsp)
movsd 0x30(%rsp), %xmm0
ucomisd 0x38(%rsp), %xmm0
jbe 0x1aa8
movsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x38(%rsp)
movl 0x78(%rsp), %eax
movl %eax, 0x48(%rsp)
movl 0x74(%rsp), %eax
movl %eax, 0x44(%rsp)
jmp 0x1aaa
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x1a31
jmp 0x1abc
movl 0x78(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x78(%rsp)
jmp 0x1a00
movsd 0x38(%rsp), %xmm0
callq 0x1ed0
testb $0x1, %al
jne 0x1add
jmp 0x1aea
movl $0xffffff9b, 0x7c(%rsp) # imm = 0xFFFFFF9B
jmp 0x1dcb
movl 0x44(%rsp), %edx
movq 0x50(%rsp), %rax
movslq 0x48(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movq 0x88(%rsp), %rdi
movl 0x48(%rsp), %esi
movl 0x44(%rsp), %edx
callq 0x1df0
movsd (%rax), %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0x88(%rsp), %rdi
movl 0x48(%rsp), %esi
callq 0x1f70
movq %rax, %rdi
movq 0x88(%rsp), %rax
movl 0x4(%rax), %esi
movsd 0x38(%rsp), %xmm0
callq 0x1ef0
movq 0x80(%rsp), %rdi
movl 0x48(%rsp), %esi
callq 0x1f70
movq %rax, %rdi
movq 0x80(%rsp), %rax
movl 0x4(%rax), %esi
movsd 0x38(%rsp), %xmm0
callq 0x1ef0
movl $0x0, 0x78(%rsp)
movl 0x78(%rsp), %eax
movq 0x88(%rsp), %rcx
cmpl (%rcx), %eax
jge 0x1cd3
movl 0x78(%rsp), %eax
cmpl 0x48(%rsp), %eax
jne 0x1b99
jmp 0x1cc3
movq 0x88(%rsp), %rdi
movl 0x78(%rsp), %esi
callq 0x1f70
movq %rax, 0x28(%rsp)
movq 0x88(%rsp), %rdi
movl 0x48(%rsp), %esi
callq 0x1f70
movq %rax, 0x20(%rsp)
movq 0x28(%rsp), %rax
movslq 0x44(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x18(%rsp)
movl $0x0, 0x74(%rsp)
movl 0x74(%rsp), %eax
movq 0x88(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jge 0x1c67
movq 0x58(%rsp), %rax
movslq 0x74(%rsp), %rcx
cmpl $0x0, (%rax,%rcx,4)
jne 0x1c0d
movl 0x74(%rsp), %eax
cmpl 0x44(%rsp), %eax
jne 0x1c0f
jmp 0x1c57
movq 0x20(%rsp), %rax
movslq 0x74(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movsd 0x18(%rsp), %xmm2
movq 0x28(%rsp), %rax
movslq 0x74(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm1
movq %xmm0, %rdx
movabsq $-0x8000000000000000, %rsi # imm = 0x8000000000000000
xorq %rsi, %rdx
movq %rdx, %xmm0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, (%rax,%rcx,8)
movl 0x74(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x74(%rsp)
jmp 0x1be2
movq 0x80(%rsp), %rdi
movl 0x78(%rsp), %esi
callq 0x1f70
movq %rax, 0x8(%rsp)
movq 0x80(%rsp), %rdi
movl 0x48(%rsp), %esi
callq 0x1f70
movq 0x8(%rsp), %rdi
movq %rax, %rsi
movq 0x80(%rsp), %rax
movl 0x4(%rax), %edx
movsd 0x18(%rsp), %xmm0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
callq 0x1ff0
movl 0x78(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x78(%rsp)
jmp 0x1b76
movq 0x58(%rsp), %rax
movslq 0x44(%rsp), %rcx
movl $0x1, (%rax,%rcx,4)
movq 0x60(%rsp), %rax
movslq 0x48(%rsp), %rcx
movl $0x1, (%rax,%rcx,4)
movl 0x4c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x4c(%rsp)
jmp 0x19cb
movl $0x0, 0x78(%rsp)
movl 0x78(%rsp), %eax
movq 0x80(%rsp), %rcx
cmpl (%rcx), %eax
jge 0x1dc9
movq 0x50(%rsp), %rax
movslq 0x78(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0x74(%rsp)
movl 0x78(%rsp), %eax
cmpl 0x74(%rsp), %eax
je 0x1db7
movq 0x80(%rsp), %rdi
movl 0x78(%rsp), %esi
callq 0x1f70
movq %rax, (%rsp)
movq 0x80(%rsp), %rdi
movl 0x74(%rsp), %esi
callq 0x1f70
movq (%rsp), %rdi
movq %rax, %rsi
movq 0x80(%rsp), %rax
movl 0x4(%rax), %edx
callq 0x2060
movq 0x50(%rsp), %rax
movslq 0x74(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0x14(%rsp)
movq 0x50(%rsp), %rax
movslq 0x78(%rsp), %rcx
movl (%rax,%rcx,4), %edx
movq 0x50(%rsp), %rax
movslq 0x74(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movl 0x14(%rsp), %edx
movq 0x50(%rsp), %rax
movslq 0x78(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
jmp 0x1db7
jmp 0x1db9
movl 0x78(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x78(%rsp)
jmp 0x1d0d
jmp 0x1dcb
movq 0x68(%rsp), %rdi
callq 0x1030
movl 0x7c(%rsp), %eax
movl %eax, 0x94(%rsp)
movl 0x94(%rsp), %eax
addq $0x98, %rsp
retq
nop