// File: /workspace/github_cpp_makefile_star2_O3/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 $0x28, %rsp
movq %rdi, %r14
imulq %rsi, %rdx
cmpq %rcx, %rdx
movq %rcx, (%rsp)
movq %rsi, 0x18(%rsp)
movq %rdx, 0x8(%rsp)
jle 0x3b94
leaq (%r14,%rdx,4), %r12
leaq (%r14,%rcx,4), %r15
leaq (,%rsi,4), %rbx
xorl %ebp, %ebp
movq %r15, %rax
movl (%rax), %ecx
cmpl %ebp, %ecx
cmoval %ecx, %ebp
addq %rbx, %rax
cmpq %r12, %rax
jb 0x3b4f
leal 0x2(%rbp), %edi
movl $0x8, %esi
callq 0x20f0
testq %rax, %rax
je 0x3c9c
movq %rax, %r13
movq 0x8(%rsp), %rax
cmpq (%rsp), %rax
jle 0x3bb1
movl (%r15), %eax
incq 0x8(%r13,%rax,8)
addq %rbx, %r15
cmpq %r12, %r15
jb 0x3b82
jmp 0x3bb1
movl $0x2, %edi
movl $0x8, %esi
callq 0x20f0
testq %rax, %rax
je 0x3c9c
movq %rax, %r13
xorl %ebp, %ebp
movl %ebp, %eax
leaq (,%rax,8), %rax
addq %r13, %rax
movq $0x0, (%r13)
leaq -0x8(%r13), %rcx
xorl %edx, %edx
movq 0x8(%rsp), %rbx
addq 0x10(%rcx), %rdx
movq %rdx, 0x10(%rcx)
addq $0x8, %rcx
cmpq %rax, %rcx
jb 0x3bd1
leaq (,%rbx,4), %rbp
movq %rbp, %rdi
callq 0x21f0
testq %rax, %rax
je 0x3c9c
movq %rax, 0x10(%rsp)
movq %rax, %rdi
movq %r14, 0x20(%rsp)
movq %r14, %rsi
movq %rbp, %rdx
callq 0x2140
testq %rbx, %rbx
movq (%rsp), %rax
movq 0x18(%rsp), %rcx
jle 0x3c7c
movq 0x10(%rsp), %rbp
leaq (,%rbx,4), %rbx
addq %rbp, %rbx
leaq (,%rcx,4), %r12
movl (%rbp,%rax,4), %r15d
movq (%r13,%r15,8), %r14
testq %rcx, %rcx
je 0x3c6c
movq %r14, %rax
imulq %rcx, %rax
movq 0x20(%rsp), %rcx
leaq (%rcx,%rax,4), %rdi
movq %rbp, %rsi
movq %r12, %rdx
callq 0x2140
movq 0x18(%rsp), %rcx
movq (%rsp), %rax
incq %r14
movq %r14, (%r13,%r15,8)
addq %r12, %rbp
cmpq %rbx, %rbp
jb 0x3c39
movq 0x10(%rsp), %rdi
callq 0x21d0
movq %r13, %rdi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x21d0
leaq 0x251b(%rip), %rdi      # 0x61be
callq 0x390d