// File: Kingsford-Group[P]ghost2/include/hungarian.hpp
// Function: kuhn_match(float**, unsigned long, unsigned long)
ssize_t** kuhn_match(cell** table, size_t n, size_t m)
{
    size_t i;
    
    /* not copying table since it will only be used once */
    
    kuhn_reduceRows(table, n, m);
    byte** marks = kuhn_mark(table, n, m);
    
    boolean* rowCovered = new boolean[n];
    boolean* colCovered = new boolean[m];
    for (i = 0; i < n; i++)
    {
        *(rowCovered + i) = false;
        *(colCovered + i) = false;
    }
    for (i = n; i < m; i++)
        *(colCovered + i) = false;
    
    size_t* altRow = new size_t[n*m];
    size_t* altCol = new size_t[n*m];
    
    ssize_t* rowPrimes = new ssize_t[n];
    ssize_t* colMarks  = new ssize_t[m];
    
    size_t* prime;
    
    for (;;)
    {
	if (kuhn_isDone(marks, colCovered, n, m))
	    break;
	
        for (;;)
	{
	    prime = kuhn_findPrime(table, marks, rowCovered, colCovered, n, m);
	    if (prime != null)
	    {
		kuhn_altMarks(marks, altRow, altCol, colMarks, rowPrimes, prime, n, m);
		for (i = 0; i < n; i++)
		{
		    *(rowCovered + i) = false;
		    *(colCovered + i) = false;
		}
		for (i = n; i < m; i++)
		    *(colCovered + i) = false;
		delete[](prime);
		break;
	    }
	    kuhn_addAndSubtract(table, rowCovered, colCovered, n, m);
	}
    }
    
    delete[](rowCovered);
    delete[](colCovered);
    delete[](altRow);
    delete[](altCol);
    delete[](rowPrimes);
    delete[](colMarks);
    
    ssize_t** rc = kuhn_assign(marks, n, m);
    
    for (i = 0; i < n; i++)
        delete[](*(marks + i));
    delete[](marks);
    
    return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x1b340
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x1b420
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rdi
callq 0x10040
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rdi
callq 0x10040
movq %rax, -0x38(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x10(%rbp), %rax
jae 0x1b01f
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x38(%rbp), %rax
movq -0x20(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x1afef
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x1b04b
movq -0x38(%rbp), %rax
movq -0x20(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x1b027
movq -0x10(%rbp), %rax
imulq -0x18(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x10040
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
imulq -0x18(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x10040
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x10040
movq %rax, -0x50(%rbp)
movq -0x18(%rbp), %rax
movl $0x8, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
callq 0x10040
movq %rax, -0x58(%rbp)
movq -0x28(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq -0x10(%rbp), %rdx
movq -0x18(%rbp), %rcx
callq 0x1b630
cmpb $0x0, %al
je 0x1b117
jmp 0x1b213
jmp 0x1b119
movq -0x8(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
movq -0x38(%rbp), %rcx
movq -0x10(%rbp), %r8
movq -0x18(%rbp), %r9
callq 0x1b710
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
je 0x1b1f0
movq -0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq -0x58(%rbp), %rcx
movq -0x50(%rbp), %r8
movq -0x60(%rbp), %r9
movq -0x10(%rbp), %r10
movq -0x18(%rbp), %rax
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x1be80
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x10(%rbp), %rax
jae 0x1b1ab
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x38(%rbp), %rax
movq -0x20(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x1b17b
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x1b1d7
movq -0x38(%rbp), %rax
movq -0x20(%rbp), %rcx
movb $0x0, (%rax,%rcx)
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x1b1b3
movq -0x60(%rbp), %rax
movq %rax, -0x70(%rbp)
cmpq $0x0, %rax
je 0x1b1ee
movq -0x70(%rbp), %rdi
callq 0x10940
jmp 0x1b20e
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %r8
callq 0x1c170
jmp 0x1b119
jmp 0x1b0f9
movq -0x30(%rbp), %rax
movq %rax, -0x78(%rbp)
cmpq $0x0, %rax
je 0x1b22a
movq -0x78(%rbp), %rdi
callq 0x10940
movq -0x38(%rbp), %rax
movq %rax, -0x80(%rbp)
cmpq $0x0, %rax
je 0x1b241
movq -0x80(%rbp), %rdi
callq 0x10940
movq -0x40(%rbp), %rax
movq %rax, -0x88(%rbp)
cmpq $0x0, %rax
je 0x1b25e
movq -0x88(%rbp), %rdi
callq 0x10940
movq -0x48(%rbp), %rax
movq %rax, -0x90(%rbp)
cmpq $0x0, %rax
je 0x1b27b
movq -0x90(%rbp), %rdi
callq 0x10940
movq -0x50(%rbp), %rax
movq %rax, -0x98(%rbp)
cmpq $0x0, %rax
je 0x1b298
movq -0x98(%rbp), %rdi
callq 0x10940
movq -0x58(%rbp), %rax
movq %rax, -0xa0(%rbp)
cmpq $0x0, %rax
je 0x1b2b5
movq -0xa0(%rbp), %rdi
callq 0x10940
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x1c2f0
movq %rax, -0x68(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x10(%rbp), %rax
jae 0x1b311
movq -0x28(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0xa8(%rbp)
cmpq $0x0, %rax
je 0x1b301
movq -0xa8(%rbp), %rdi
callq 0x10940
jmp 0x1b303
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x1b2d2
movq -0x28(%rbp), %rax
movq %rax, -0xb0(%rbp)
cmpq $0x0, %rax
je 0x1b32e
movq -0xb0(%rbp), %rdi
callq 0x10940
movq -0x68(%rbp), %rax
addq $0xc0, %rsp
popq %rbp
retq
nopl (%rax,%rax)