// File: /workspace/github_cpp_makefile_star2_O1/EnderGed[P]fast-random-walk/HelperFunctions.cpp
// Function: countSort2D(unsigned int*, unsigned long, unsigned long, unsigned long)
void countSort2D(uint * const arr, size_t const size_x, size_t const size_y, size_t column)
{
	// Prepare break condition
	uint * const arrEnd = arr + size_x * size_y;

	// Determine maximum index
	uint maxIndex = 0;
	for(uint * pos = arr + column; pos < arrEnd; pos += size_x)
		if(*pos > maxIndex) maxIndex = *pos;

	// Allocate adjacency list
	read_t * const adj = (read_t*)calloc((maxIndex + 2), sizeof(*adj));
	read_t * const counts = adj + 1;

	if(!adj) printError("Memory allocation failed");

	// Count occurences of each index
	for(uint * pos = arr + column; pos < arrEnd; pos += size_x) ++(counts[*pos]);

	// Convert occurency counts to real adjacency list
	read_t * const adj_end = adj + maxIndex + 1;
	adj[0] = 0;
	for(read_t * pos_adj = adj; pos_adj < adj_end; ++pos_adj) pos_adj[1] += pos_adj[0];

	// Copy arr
	uint * arrCpy = (uint*)malloc(size_x * size_y * sizeof(*arrCpy));
	if(!arrCpy) printError("Memory allocation failed");
	memcpy(arrCpy, arr, size_x * size_y * sizeof(*arrCpy));
	uint const * const arrCpyEnd = arrCpy + size_x * size_y;

	// Move rows back to arr but to the correct position
	for(uint const * cpyPos = arrCpy; cpyPos < arrCpyEnd; cpyPos += size_x)
	{
		for(size_t i = 0; i < size_x; ++i) arr[adj[cpyPos[column]] * size_x + i] = cpyPos[i];
		++adj[cpyPos[column]];
	}

	// Clean up
	free(arrCpy);
	free(adj);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rcx, %rbx
movq %rsi, %r14
imulq %rsi, %rdx
leaq (%rdi,%rdx,4), %rbp
movq %rdi, 0x8(%rsp)
leaq (%rdi,%rcx,4), %r12
xorl %r15d, %r15d
movq %rdx, 0x10(%rsp)
cmpq %rcx, %rdx
jle 0x3bab
leaq (,%r14,4), %rax
xorl %r15d, %r15d
movq %r12, %rcx
movl (%rcx), %edx
cmpl %r15d, %edx
cmoval %edx, %r15d
addq %rax, %rcx
cmpq %rbp, %rcx
jb 0x3b9a
leal 0x2(%r15), %edi
movl $0x8, %esi
callq 0x20f0
testq %rax, %rax
je 0x3ccc
movq %rax, %r13
movq 0x10(%rsp), %rsi
cmpq %rbx, %rsi
jle 0x3be8
leaq (,%r14,4), %rax
movl (%r12), %ecx
incq 0x8(%r13,%rcx,8)
addq %rax, %r12
cmpq %rbp, %r12
jb 0x3bd7
movl %r15d, %eax
leaq 0x8(,%rax,8), %rcx
addq %r13, %rcx
movq $0x0, (%r13)
cmpq %rcx, %r13
jae 0x3c2a
leaq (,%rax,8), %rax
addq %r13, %rax
movq (%r13), %rcx
movq %r13, %rdx
addq $-0x8, %rdx
addq 0x10(%rdx), %rcx
movq %rcx, 0x10(%rdx)
addq $0x8, %rdx
cmpq %rax, %rdx
jb 0x3c19
leaq (,%rsi,4), %rbp
movq %rbp, %rdi
movq %rsi, %r15
callq 0x21f0
testq %rax, %rax
je 0x3ccc
movq %rax, (%rsp)
movq %rax, %rdi
movq 0x8(%rsp), %rsi
movq %rbp, %rdx
callq 0x2140
testq %r15, %r15
jle 0x3cad
movq (%rsp), %rbp
leaq (,%r15,4), %r15
addq %rbp, %r15
leaq (,%r14,4), %r12
testq %r14, %r14
je 0x3c9c
movl (%rbp,%rbx,4), %eax
movq (%r13,%rax,8), %rax
imulq %r14, %rax
movq 0x8(%rsp), %rcx
leaq (%rcx,%rax,4), %rdi
movq %rbp, %rsi
movq %r12, %rdx
callq 0x2140
movl (%rbp,%rbx,4), %eax
incq (%r13,%rax,8)
addq %r12, %rbp
cmpq %r15, %rbp
jb 0x3c76
movq (%rsp), %rdi
callq 0x21d0
movq %r13, %rdi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x21d0
leaq 0x24eb(%rip), %rdi      # 0x61be
callq 0x3955