// File: lluchs[P]sparsearray/main.cpp
// Function: main
int main(int argc, char **argv)
{
	const size_t list_size = 10000;

	int opt;
	while ((opt = getopt(argc, argv, "l:i:s:a:")) != -1)
	{
		switch (opt)
		{
		// No error handling. Don't pass invalid values.
		case 'i': iterations = std::atoi(optarg); break;
		case 's': seed = std::strtoull(optarg, nullptr, 10); break;
		case 'a': addmod = std::atoi(optarg); break;
		default: std::cerr << "Invalid option " << (char) opt << std::endl;
		}
	}
	std::cout << "iterations = " << std::to_string(iterations) << std::endl;
	std::cout << "seed = " << std::to_string(seed) << std::endl;
	std::cout << "addmod = " << std::to_string(addmod) << std::endl;
	std::cout << "data size = " << sizeof(C4PXS[list_size]) << " byte" << std::endl << std::endl;

	run_benchmark<BitmapSA<C4PXS, list_size>>("BitmapSA");
	run_benchmark<ChunkSA<C4PXS, list_size>>("ChunkSA");
	run_benchmark<StaticChunkSA<C4PXS, list_size>>("StaticChunkSA");
	run_benchmark<LinkedListSA<C4PXS, list_size>>("LinkedListSA");
	run_benchmark<LinkedListBitmapSA<C4PXS, list_size>>("LinkedListBitmapSA");
	run_benchmark<DoubleLinkedListSA<C4PXS, list_size>>("DoubleLinkedListSA");
	run_benchmark<UnorderedLinkedListSA<C4PXS, list_size>>("UnorderedLinkedListSA");
	run_benchmark<ReorderingSA<C4PXS, list_size>>("ReorderingSA");

	return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x2710, -0x18(%rbp)    # imm = 0x2710
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
leaq 0x6c79(%rip), %rdx      # 0x9018
callq 0x2060
movl %eax, -0x1c(%rbp)
cmpl $-0x1, %eax
je 0x245e
movl -0x1c(%rbp), %eax
movl %eax, -0x94(%rbp)
subl $0x61, %eax
je 0x2412
jmp 0x23c0
movl -0x94(%rbp), %eax
subl $0x69, %eax
je 0x23da
jmp 0x23cd
movl -0x94(%rbp), %eax
subl $0x73, %eax
je 0x23f1
jmp 0x2429
movq 0xabdf(%rip), %rax      # 0xcfc0
movq (%rax), %rdi
callq 0x21c0
movl %eax, 0xad39(%rip)      # 0xd128
jmp 0x2459
movq 0xabc8(%rip), %rax      # 0xcfc0
movq (%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x2190
movq %rax, 0xad20(%rip)      # 0xd130
jmp 0x2459
movq 0xaba7(%rip), %rax      # 0xcfc0
movq (%rax), %rdi
callq 0x21c0
movl %eax, 0xad11(%rip)      # 0xd138
jmp 0x2459
movq 0xabc0(%rip), %rdi      # 0xcff0
leaq 0x6bea(%rip), %rsi      # 0x9021
callq 0x2120
movq %rax, %rdi
movl -0x1c(%rbp), %eax
movsbl %al, %esi
callq 0x2170
movq %rax, %rdi
movq 0xab64(%rip), %rsi      # 0xcfb8
callq 0x2130
jmp 0x2391
movq 0xab6b(%rip), %rdi      # 0xcfd0
leaq 0x6bc5(%rip), %rsi      # 0x9031
callq 0x2120
movq %rax, -0xb0(%rbp)
movl 0xacaa(%rip), %esi      # 0xd128
leaq -0x40(%rbp), %rdi
movq %rdi, -0xa8(%rbp)
callq 0x34b0
movq -0xb0(%rbp), %rdi
movq -0xa8(%rbp), %rsi
callq 0x2110
movq %rax, -0xa0(%rbp)
jmp 0x24aa
movq -0xa0(%rbp), %rdi
movq 0xab00(%rip), %rsi      # 0xcfb8
callq 0x2130
jmp 0x24bf
leaq -0x40(%rbp), %rdi
callq 0x20b0
movq 0xab01(%rip), %rdi      # 0xcfd0
leaq 0x6b69(%rip), %rsi      # 0x903f
callq 0x2120
movq %rax, -0xc8(%rbp)
movq 0xac47(%rip), %rsi      # 0xd130
leaq -0x70(%rbp), %rdi
movq %rdi, -0xc0(%rbp)
callq 0x35d0
movq -0xc8(%rbp), %rdi
movq -0xc0(%rbp), %rsi
callq 0x2110
movq %rax, -0xb8(%rbp)
jmp 0x2515
movq -0xb8(%rbp), %rdi
movq 0xaa95(%rip), %rsi      # 0xcfb8
callq 0x2130
jmp 0x252a
leaq -0x70(%rbp), %rdi
callq 0x20b0
movq 0xaa96(%rip), %rdi      # 0xcfd0
leaq 0x6b06(%rip), %rsi      # 0x9047
callq 0x2120
movq %rax, -0xe0(%rbp)
movl 0xabe5(%rip), %esi      # 0xd138
leaq -0x90(%rbp), %rdi
movq %rdi, -0xd8(%rbp)
callq 0x34b0
movq -0xe0(%rbp), %rdi
movq -0xd8(%rbp), %rsi
callq 0x2110
movq %rax, -0xd0(%rbp)
jmp 0x2582
movq -0xd0(%rbp), %rdi
movq 0xaa28(%rip), %rsi      # 0xcfb8
callq 0x2130
jmp 0x2597
leaq -0x90(%rbp), %rdi
callq 0x20b0
movq 0xaa26(%rip), %rdi      # 0xcfd0
leaq 0x6aa0(%rip), %rsi      # 0x9051
callq 0x2120
movq %rax, %rdi
movl $0x30d40, %esi          # imm = 0x30D40
callq 0x2070
movq %rax, %rdi
leaq 0x6a91(%rip), %rsi      # 0x905e
callq 0x2120
movq %rax, %rdi
movq 0xa9dc(%rip), %rsi      # 0xcfb8
callq 0x2130
movq %rax, %rdi
movq 0xa9cd(%rip), %rsi      # 0xcfb8
callq 0x2130
leaq 0x6a85(%rip), %rdi      # 0x907c
callq 0x26b0
leaq 0x6a67(%rip), %rdi      # 0x906a
callq 0x2870
leaq 0x6a55(%rip), %rdi      # 0x9064
callq 0x2a30
leaq 0x6a86(%rip), %rdi      # 0x90a1
callq 0x2bf0
leaq 0x6a4b(%rip), %rdi      # 0x9072
callq 0x2db0
leaq 0x6a52(%rip), %rdi      # 0x9085
callq 0x2f70
leaq 0x6a59(%rip), %rdi      # 0x9098
callq 0x3130
leaq 0x6a63(%rip), %rdi      # 0x90ae
callq 0x32f0
xorl %eax, %eax
addq $0xe0, %rsp
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x20b0
jmp 0x26a1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x70(%rbp), %rdi
callq 0x20b0
jmp 0x26a1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x20b0
movq -0x48(%rbp), %rdi
callq 0x21e0
nopw (%rax,%rax)