// File: lluchs[P]sparsearray/main.cpp
// Function: BenchmarkResult benchmark<ChunkSA<C4PXS, 10000ul, 500ul>>(int, unsigned long, int)
BenchmarkResult benchmark(int iterations, uint64_t seed, int addmod)
{
	uint64_t r = seed;
	auto rand = [&r]() { return r = r * 6364136223846793005 + 1442695040888963407; };
	SparseArray array;
	BenchmarkResult result = {0};

	for (int i = 0; i < iterations; i++)
	{
		// Add new PXS periodically.
		if (i % addmod == 0)
			for (int j = 0; j < 10; j++)
			{
				auto npxs = array.New();
				if (npxs)
				{
					npxs->Mat = 1;
					npxs->x = 0; npxs->y = 0;
					npxs->xdir = (int) (rand() % 100) - 50;
					npxs->ydir = (int) (rand() % 100) - 50;
				}
			}
		// walk through the array and do stuff
		for (auto& pxs : array)
		{
			pxs.x += pxs.xdir; pxs.y += pxs.ydir;
			if (std::abs(pxs.x + pxs.y) > 10000)
			{
				pxs.Mat = C4PXS::MNone;
				array.Delete(&pxs);
			}
		}
	}

	for (auto& pxs : array)
	{
		result.count++;
		result.sum += pxs.x + pxs.y;
	}
	return result;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x790, %rsp            # imm = 0x790
movl %edi, -0xc(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
leaq -0x28(%rbp), %rax
movq %rax, -0x30(%rbp)
leaq -0x658(%rbp), %rdi
callq 0x4a70
leaq -0x8(%rbp), %rdi
xorl %esi, %esi
movl $0x8, %edx
callq 0x20a0
movl $0x0, -0x65c(%rbp)
movl -0x65c(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x4964
movl -0x65c(%rbp), %eax
cltd
idivl -0x1c(%rbp)
cmpl $0x0, %edx
jne 0x4811
movl $0x0, -0x660(%rbp)
cmpl $0xa, -0x660(%rbp)
jge 0x480f
leaq -0x658(%rbp), %rdi
callq 0x4ae0
movq %rax, -0x740(%rbp)
jmp 0x4719
movq -0x740(%rbp), %rax
movq %rax, -0x668(%rbp)
cmpq $0x0, -0x668(%rbp)
je 0x47f9
movq -0x668(%rbp), %rax
movl $0x1, (%rax)
movq -0x668(%rbp), %rax
movl $0x0, 0x4(%rax)
movq -0x668(%rbp), %rax
movl $0x0, 0x8(%rax)
leaq -0x30(%rbp), %rdi
callq 0x4cb0
movq %rax, -0x748(%rbp)
jmp 0x4770
movq -0x748(%rbp), %rcx
movq %rcx, %rax
shrq $0x2, %rax
movabsq $0x28f5c28f5c28f5c3, %rdx # imm = 0x28F5C28F5C28F5C3
mulq %rdx
movl %edx, %eax
shrl $0x2, %eax
imull $0x64, %eax, %eax
subl %eax, %ecx
addl $-0x32, %ecx
movq -0x668(%rbp), %rax
movl %ecx, 0xc(%rax)
leaq -0x30(%rbp), %rdi
callq 0x4cb0
movq %rax, -0x750(%rbp)
jmp 0x47b4
movq -0x750(%rbp), %rax
movl $0x64, %ecx
xorl %edx, %edx
divq %rcx
movl %edx, %ecx
subl $0x32, %ecx
movq -0x668(%rbp), %rax
movl %ecx, 0x10(%rax)
jmp 0x47f9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x670(%rbp)
movl %eax, -0x674(%rbp)
leaq -0x658(%rbp), %rdi
callq 0x4f90
jmp 0x4a64
jmp 0x47fb
movl -0x660(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x660(%rbp)
jmp 0x46f7
jmp 0x4811
leaq -0x658(%rbp), %rax
movq %rax, -0x680(%rbp)
movq -0x680(%rbp), %rsi
leaq -0x698(%rbp), %rdi
callq 0x4cf0
jmp 0x4834
movq -0x680(%rbp), %rsi
leaq -0x6b0(%rbp), %rdi
callq 0x4d20
jmp 0x4849
jmp 0x484b
movq -0x6a0(%rbp), %rax
movq %rax, -0x6c0(%rbp)
movups -0x6b0(%rbp), %xmm0
movaps %xmm0, -0x6d0(%rbp)
movq -0x6c0(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
movaps -0x6d0(%rbp), %xmm0
movups %xmm0, (%rax)
leaq -0x698(%rbp), %rdi
callq 0x4d50
movb %al, -0x751(%rbp)
jmp 0x4893
movb -0x751(%rbp), %al
testb $0x1, %al
jne 0x48a2
jmp 0x494e
leaq -0x698(%rbp), %rdi
callq 0x4db0
movq %rax, -0x760(%rbp)
jmp 0x48b7
movq -0x760(%rbp), %rax
movq %rax, -0x6d8(%rbp)
movq -0x6d8(%rbp), %rax
movl 0xc(%rax), %ecx
movq -0x6d8(%rbp), %rax
addl 0x4(%rax), %ecx
movl %ecx, 0x4(%rax)
movq -0x6d8(%rbp), %rax
movl 0x10(%rax), %ecx
movq -0x6d8(%rbp), %rax
addl 0x8(%rax), %ecx
movl %ecx, 0x8(%rax)
movq -0x6d8(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x6d8(%rbp), %rcx
addl 0x8(%rcx), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
cmpl $0x2710, %eax           # imm = 0x2710
jle 0x4939
movq -0x6d8(%rbp), %rax
movl $0x0, (%rax)
movq -0x6d8(%rbp), %rsi
leaq -0x658(%rbp), %rdi
callq 0x4de0
jmp 0x4937
jmp 0x4939
jmp 0x493b
leaq -0x698(%rbp), %rdi
callq 0x4f70
jmp 0x4949
jmp 0x484b
jmp 0x4950
movl -0x65c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x65c(%rbp)
jmp 0x46cb
leaq -0x658(%rbp), %rax
movq %rax, -0x6e0(%rbp)
movq -0x6e0(%rbp), %rsi
leaq -0x6f8(%rbp), %rdi
callq 0x4cf0
jmp 0x4987
movq -0x6e0(%rbp), %rsi
leaq -0x710(%rbp), %rdi
callq 0x4d20
jmp 0x499c
jmp 0x499e
movq -0x700(%rbp), %rax
movq %rax, -0x720(%rbp)
movups -0x710(%rbp), %xmm0
movaps %xmm0, -0x730(%rbp)
movq -0x720(%rbp), %rcx
movq %rsp, %rax
movq %rcx, 0x10(%rax)
movaps -0x730(%rbp), %xmm0
movups %xmm0, (%rax)
leaq -0x6f8(%rbp), %rdi
callq 0x4d50
movb %al, -0x761(%rbp)
jmp 0x49e6
movb -0x761(%rbp), %al
testb $0x1, %al
jne 0x49f2
jmp 0x4a4b
leaq -0x6f8(%rbp), %rdi
callq 0x4db0
movq %rax, -0x770(%rbp)
jmp 0x4a07
movq -0x770(%rbp), %rax
movq %rax, -0x738(%rbp)
movl -0x8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8(%rbp)
movq -0x738(%rbp), %rax
movl 0x4(%rax), %eax
movq -0x738(%rbp), %rcx
addl 0x8(%rcx), %eax
addl -0x4(%rbp), %eax
movl %eax, -0x4(%rbp)
leaq -0x6f8(%rbp), %rdi
callq 0x4f70
jmp 0x4a46
jmp 0x499e
leaq -0x658(%rbp), %rdi
callq 0x4f90
movq -0x8(%rbp), %rax
addq $0x790, %rsp            # imm = 0x790
popq %rbp
retq
movq -0x670(%rbp), %rdi
callq 0x21e0