// File: /workspace/github_cpp_makefile_star2_O3/xdsopl[P]FEC/testbench.cc
// Function: void test_bch<24, 1, 65343, 16, 65581, unsigned short>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, BoseChaudhuriHocquenghem<24, 1, 65343, GF::Types<16, 65581, unsigned short>>&, unsigned short*, unsigned short*, std::vector<unsigned char, std::allocator<unsigned char>>&)
void test_bch(std::string name, BoseChaudhuriHocquenghem<NR, FCR, K, GF::Types<M, P, TYPE>> &bch, TYPE *code, TYPE *target, std::vector<uint8_t> &data)
{
	std::cout << "testing: " << name << std::endl;

	{
		bch.encode(code);
		bool error = false;
		for (int i = 0; i < bch.N; ++i)
			error |= code[i] != target[i];
		if (error)
			std::cout << "encoder error!" << std::endl;
		assert(!error);
		//print_table(code + K, "parity", bch.NP);
		error = bch.decode(code);
		if (error)
			std::cout << "decoder error!" << std::endl;
		assert(!error);
		int pos = 0, cap = 0, corrupt = 0, erasures_count = 0;
		TYPE erasures[NR];
		// need one root per erasure
		for (int i = 0; pos < bch.N && cap+1 <= NR && i < NR/2; ++i, ++corrupt, ++pos, ++cap)
			code[erasures[erasures_count++] = pos] ^= 1;
		// need two roots per error
		for (int i = 0; pos < bch.N && cap+2 <= NR && i < NR/2; ++i, ++corrupt, ++pos, cap+=2)
			code[pos] ^= 1;
		int corrected = bch.decode(code, erasures, erasures_count);
		if (corrupt != corrected)
			std::cout << "decoder error: expected " << corrupt << " but got " << corrected << std::endl;
		assert(corrupt == corrected);
		TYPE syndromes[NR];
		if (corrected >= 0 && bch.compute_syndromes(code, syndromes)) {
			std::cout << "decoder error: result of correction is not a codeword!" << std::endl;
			assert(false);
		}
		error = false;
		for (int i = 0; i < bch.N; ++i)
			error |= code[i] != target[i];
		if (error)
			std::cout << "decoder error: code doesnt match target" << std::endl;
		assert(!error);
	}
	int blocks = (8 * data.size() + K - 1) / K;
	TYPE *coded = new TYPE[bch.N * blocks];
	{
		unsigned pos = 0;
		for (unsigned byte : data) {
			for (int bit = 0; bit < 8; ++bit) {
				coded[pos++] = (byte >> bit) & 1;
				if (pos % bch.N >= K)
					pos += bch.NP;
			}
		}
	}
	{
		auto start = std::chrono::system_clock::now();
		for (int i = 0; i < blocks; ++i)
			bch.encode(coded + i * bch.N);
		auto end = std::chrono::system_clock::now();
		auto msec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
		int mbs = (data.size() + msec.count() / 2) / msec.count();
		int bytes = (bch.N * blocks) / 8;
		float redundancy = (100.0f*(bytes-data.size())) / data.size();
		std::cout << "encoding of " << data.size() << " random bytes into " << bytes << " codeword bytes (" << std::setprecision(1) << std::fixed << redundancy << "% redundancy) in " << blocks << " blocks took " << msec.count() << " milliseconds (" << mbs << "KB/s)." << std::endl;
	}
	std::random_device rd;
	std::default_random_engine generator(rd());
	std::uniform_int_distribution<int> pos_dist(0, bch.N-1);
	auto rnd_pos = std::bind(pos_dist, generator);
	std::vector<uint8_t> recovered(data.size());
	TYPE *tmp = new TYPE[bch.N * blocks];
	TYPE *erasures = new TYPE[NR * blocks];
	for (int places = 0; places <= NR; ++places) {
		for (int erasures_count = 0; erasures_count <= places; ++erasures_count) {
			for (int i = 0; i < bch.N * blocks; ++i)
				tmp[i] = coded[i];
			int corrupt = 0;
			for (int i = 0; i < blocks; ++i) {
				for (int j = 0; j < places; ++j) {
					erasures[i*NR + j] = rnd_pos();
					for (int k = 0; k < j;) {
						if (erasures[i*NR + k++] == erasures[i*NR + j]) {
							erasures[i*NR + j] = rnd_pos();
							k = 0;
						}
					}
					tmp[i * bch.N + erasures[i*NR + j]] ^= 1;
					++corrupt;
				}
			}
			int corrected = 0, wrong = 0;
			auto start = std::chrono::system_clock::now();
			for (int i = 0; i < blocks; ++i) {
				int result = bch.decode(tmp + i * bch.N, erasures + i * NR, erasures_count);
				if (places > NR/2 && places > erasures_count && result >= 0)
					for (int j = i * bch.N; j < (i + 1) * bch.N; ++j)
						wrong += coded[j] != tmp[j];
				corrected += result;
			}
			auto end = std::chrono::system_clock::now();
			auto msec = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
			int bytes = (bch.N * blocks) / 8;
			int mbs = (bytes + msec.count() / 2) / msec.count();
			std::cout << "decoding with " << places << " errors and " << erasures_count << " known erasures per block took " << msec.count() << " milliseconds (" << mbs << "KB/s).";
			if (corrupt != corrected || wrong)
				std::cout << " expected " << corrupt << " corrected errors but got " << corrected << " and " << wrong << " wrong corrections.";
			std::cout << std::endl;
			assert((places > NR/2 && places > erasures_count) || (corrupt == corrected && !wrong));
			int left = 0;
			for (int i = 0; i < bch.N * blocks; ++i)
				left += tmp[i] > 1;
			if (left)
				std::cout << "correction left GF(2) " << left << " times!" << std::endl;
			if (corrupt == corrected && !wrong) {
				unsigned acc = 0, bit = 0, pos = 0;
				for (uint8_t &byte: recovered) {
					while (bit < 8) {
						acc |= (unsigned)tmp[pos++] << bit++;
						if (pos % bch.N >= K)
							pos += bch.NP;
					}
					bit -= 8;
					byte = 255 & acc;
					acc >>= 8;
				}
				for (int i = 0; i < blocks; ++i) {
					TYPE syndromes[NR];
					if (bch.compute_syndromes(tmp + i * bch.N, syndromes)) {
						std::cout << "decoder error: result of correction is not a codeword!" << std::endl;
						assert(false);
					}
				}
				if (data != recovered) {
					std::cout << "decoder error: data could not be recovered from corruption!" << std::endl;
					assert(places > NR/2 && places > erasures_count);
				}
			}
		}
	}
	delete[] erasures;
	delete[] tmp;
	delete[] coded;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1468, %rsp           # imm = 0x1468
movq %r8, 0x50(%rsp)
movq %rcx, %rbx
movq %rdx, %r14
movq %rsi, %r13
movq %rdi, %r15
movq 0xcf636(%rip), %r12     # 0xd4fd8
leaq 0x9006(%rip), %rsi      # 0xe9af
movl $0x9, %edx
movq %r12, %rdi
callq 0x2190
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq %r12, %rdi
callq 0x2190
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2140
movsbl %al, %esi
movq %r15, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20e0
movq %r13, %rdi
movq %r14, %rsi
callq 0xb674
xorl %eax, %eax
xorl %ecx, %ecx
movzwl (%r14,%rax,2), %edx
cmpw (%rbx,%rax,2), %dx
setne %dl
orb %dl, %cl
incq %rax
cmpq $0xffff, %rax           # imm = 0xFFFF
jne 0x59fe
testb $0x1, %cl
jne 0x6583
movq %r13, %rdi
movq %r14, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0xb704
testl %eax, %eax
movq 0x50(%rsp), %r15
jne 0x65bd
xorl %eax, %eax
movw %ax, 0xe0(%rsp,%rax,2)
xorb $0x1, (%r14,%rax,2)
leaq 0x1(%rax), %rcx
movq %rcx, %rax
cmpq $0xc, %rcx
jne 0x5a3e
movl $0xc, %eax
xorb $0x1, (%r14,%rax,2)
incq %rax
cmpq $0x12, %rax
jne 0x5a5d
leaq 0xe0(%rsp), %rdx
movq %r13, %rdi
movq %r14, %rsi
movl $0xc, %ecx
callq 0xb704
cmpl $0x12, %eax
jne 0x65f7
leaq 0xb0(%rsp), %rdx
movq %r13, %rdi
movq %r14, %rsi
callq 0xb7be
testl %eax, %eax
jne 0x668b
xorl %eax, %eax
xorl %ecx, %ecx
movzwl (%r14,%rax,2), %edx
cmpw (%rbx,%rax,2), %dx
setne %dl
orb %dl, %cl
incq %rax
cmpq $0xffff, %rax           # imm = 0xFFFF
jne 0x5aab
testb $0x1, %cl
jne 0x66c5
movq (%r15), %r14
movq 0x8(%r15), %r15
movq %r15, %rax
subq %r14, %rax
leaq 0xff3e(,%rax,8), %rax
movabsq $0x4030647bc14cbad9, %rcx # imm = 0x4030647BC14CBAD9
mulq %rcx
shrq $0xe, %rdx
movl %edx, %eax
shll $0x10, %eax
subl %edx, %eax
movq %rax, 0x30(%rsp)
cltq
addq %rax, %rax
movq %rdx, 0x18(%rsp)
testl %edx, %edx
movq $-0x1, %rbx
cmovnsq %rax, %rbx
movq %rbx, %rdi
callq 0x2030
movq %rax, 0x38(%rsp)
cmpq %r14, %r15
je 0x5b8c
xorl %ecx, %ecx
movl $0x80008001, %eax       # imm = 0x80008001
movq 0x38(%rsp), %r10
movzbl (%r14), %edx
xorl %esi, %esi
xorl %r8d, %r8d
btl %esi, %edx
setb %r8b
leal 0x1(%rcx), %edi
movl %ecx, %r9d
movw %r8w, (%r10,%r9,2)
movq %rdi, %r8
imulq %rax, %r8
shrq $0x2f, %r8
movl %r8d, %r9d
shll $0x10, %r9d
subl %r9d, %r8d
addl %ecx, %r8d
incl %r8d
cmpl $0xff3f, %r8d           # imm = 0xFF3F
jae 0x5b77
movl %edi, %ecx
jmp 0x5b7d
addl $0xc1, %ecx
incl %esi
cmpl $0x8, %esi
jne 0x5b3a
incq %r14
cmpq %r15, %r14
jne 0x5b34
callq 0x2050
movq %rax, %r14
cmpl $0x0, 0x18(%rsp)
jle 0x5bc3
movq 0x18(%rsp), %r12
andl $0x7fffffff, %r12d      # imm = 0x7FFFFFFF
movq 0x38(%rsp), %r15
movq %r13, %rdi
movq %r15, %rsi
callq 0xb674
addq $0x1fffe, %r15          # imm = 0x1FFFE
decq %r12
jne 0x5bac
movq %r13, 0x70(%rsp)
callq 0x2050
subq %r14, %rax
movabsq $0x431bde82d7b634db, %rcx # imm = 0x431BDE82D7B634DB
imulq %rcx
movq %rdx, %r14
sarq $0x12, %r14
movq %rdx, %rax
shrq $0x3f, %rax
movq 0x50(%rsp), %rsi
movq 0x8(%rsi), %rcx
subq (%rsi), %rcx
addq %rax, %r14
sarq $0x13, %rdx
addq %rdx, %rax
addq %rcx, %rax
xorl %edx, %edx
divq %r14
movq %rax, %r15
movq 0x30(%rsp), %rax
leal 0x7(%rax), %ebp
testl %eax, %eax
cmovnsl %eax, %ebp
sarl $0x3, %ebp
movslq %ebp, %rax
movq %rax, 0xa8(%rsp)
subq %rcx, %rax
js 0x5c33
cvtsi2ss %rax, %xmm1
jmp 0x5c48
movq %rax, %rdx
shrq %rdx
andl $0x1, %eax
orq %rdx, %rax
cvtsi2ss %rax, %xmm1
addss %xmm1, %xmm1
mulss 0x83b4(%rip), %xmm1     # 0xe004
testq %rcx, %rcx
js 0x5c5c
cvtsi2ss %rcx, %xmm0
jmp 0x5c71
movq %rcx, %rax
shrq %rax
andl $0x1, %ecx
orq %rax, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
divss %xmm0, %xmm1
movss %xmm1, 0x20(%rsp)
movq 0xcf356(%rip), %r12     # 0xd4fd8
leaq 0x8eb5(%rip), %rsi      # 0xeb3e
movl $0xc, %edx
movq %r12, %rdi
callq 0x2190
movq 0x50(%rsp), %r13
movq 0x8(%r13), %rsi
subq (%r13), %rsi
movq %r12, %rdi
callq 0x20d0
movq %rax, %r12
leaq 0x8e96(%rip), %rsi      # 0xeb4b
movl $0x13, %edx
movq %rax, %rdi
callq 0x2190
movq %r12, %rdi
movl %ebp, %esi
callq 0x2200
movq %rax, %r12
leaq 0x8e89(%rip), %rsi      # 0xeb5f
movl $0x11, %edx
movq %rax, %rdi
callq 0x2190
movq (%r12), %rax
movq -0x18(%rax), %rcx
movq $0x1, 0x8(%r12,%rcx)
movq -0x18(%rax), %rax
movl $0xfffffefb, %ecx       # imm = 0xFFFFFEFB
andl 0x18(%r12,%rax), %ecx
orl $0x4, %ecx
movl %ecx, 0x18(%r12,%rax)
xorps %xmm0, %xmm0
cvtss2sd 0x20(%rsp), %xmm0
movq %r12, %rdi
callq 0x21d0
movq %rax, %r12
leaq 0x8e4c(%rip), %rsi      # 0xeb71
movl $0x11, %edx
movq %rax, %rdi
callq 0x2190
movq %r12, %rdi
movq 0x18(%rsp), %rsi
callq 0x2200
movq %rax, %r12
leaq 0x8e3a(%rip), %rsi      # 0xeb83
movl $0xd, %edx
movq %rax, %rdi
callq 0x2190
movq %r12, %rdi
movq %r14, %rsi
callq 0x2130
movq %rax, %r14
leaq 0x8e26(%rip), %rsi      # 0xeb91
movl $0xf, %edx
movq %rax, %rdi
callq 0x2190
movq %r14, %rdi
movl %r15d, %esi
callq 0x2200
movq %rax, %r14
leaq 0x8e14(%rip), %rsi      # 0xeba1
movl $0x6, %edx
movq %rax, %rdi
callq 0x2190
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2140
movsbl %al, %esi
movq %r14, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20e0
leaq 0xe0(%rsp), %r14
movq %r14, %rdi
callq 0x28f0
movq %r14, %rdi
callq 0x21b0
movl %eax, %ecx
leaq (%rcx,%rcx,2), %rcx
shrq $0x20, %rcx
movl %eax, %edx
subl %ecx, %edx
shrl %edx
addl %ecx, %edx
shrl $0x1e, %edx
movl %edx, %ecx
shll $0x1f, %ecx
orl %edx, %ecx
leal (%rax,%rcx), %edx
cmpl $0x1, %edx
adcl %eax, %ecx
movabsq $0xfffe00000000, %rax   # imm = 0xFFFE00000000
movq %rax, 0x90(%rsp)
movq %rcx, 0x98(%rsp)
movq 0x8(%r13), %rsi
subq (%r13), %rsi
leaq 0x78(%rsp), %rdi
leaq 0xb0(%rsp), %rdx
callq 0x296a
movq 0x30(%rsp), %r14
movq %rbx, %rdi
callq 0x2030
movq 0x18(%rsp), %rbx
movq %rax, %r13
movq %rbx, %rax
shlq $0x23, %rax
leaq (%rax,%rax,2), %rax
movq %rax, %rcx
sarq $0x1f, %rcx
testq %rax, %rax
movq $-0x1, %rdi
cmovnsq %rcx, %rdi
callq 0x2030
movq %rax, %r15
cmpl $0x2, %r14d
movl $0x1, %eax
movl $0x1, 0x4c(%rsp)
cmovll %eax, %r14d
addl %r14d, %r14d
movq %r14, 0x30(%rsp)
andl $0x7fffffff, %ebx       # imm = 0x7FFFFFFF
movq %rbx, 0x60(%rsp)
movq $0x0, 0x20(%rsp)
leaq 0x90(%rsp), %r14
movl $0x0, 0x28(%rsp)
movq %r13, 0x40(%rsp)
xorl %eax, %eax
movl %eax, 0x2c(%rsp)
movl %eax, %eax
movq %rax, 0x68(%rsp)
cmpl $0x0, 0x18(%rsp)
jle 0x60a2
movq %r13, %rdi
movq 0x38(%rsp), %rsi
movq 0x30(%rsp), %rdx
callq 0x2100
movq $0x0, 0x8(%rsp)
cmpq $0x0, 0x20(%rsp)
je 0x5f81
movq 0x8(%rsp), %r12
leaq (,%r12,8), %rax
leaq (%rax,%rax,2), %rbx
leaq (%r15,%rbx,2), %rbp
leaq (%r12,%r12), %rax
shlq $0x11, %r12
subq %rax, %r12
addq 0x40(%rsp), %r12
xorl %r13d, %r13d
movq %r14, %rdi
leaq 0x98(%rsp), %rsi
movq %r14, %rdx
callq 0x8f9a
movw %ax, (%rbp,%r13,2)
testq %r13, %r13
je 0x5f6f
xorl %ecx, %ecx
leal (%rcx,%rbx), %edx
movslq %edx, %rdx
cmpw %ax, (%r15,%rdx,2)
jne 0x5f65
movq %r14, %rdi
leaq 0x98(%rsp), %rsi
movq %r14, %rdx
callq 0x8f9a
movw %ax, (%rbp,%r13,2)
xorl %ecx, %ecx
jmp 0x5f67
incl %ecx
movslq %ecx, %rdx
cmpq %rdx, %r13
jg 0x5f3b
movzwl %ax, %eax
xorb $0x1, (%r12,%rax,2)
incq %r13
cmpq 0x20(%rsp), %r13
jne 0x5f1b
movq 0x8(%rsp), %rcx
incq %rcx
movq %rcx, 0x8(%rsp)
cmpq 0x60(%rsp), %rcx
jne 0x5ee7
callq 0x2050
movq %rax, %rbx
cmpl $0x0, 0x18(%rsp)
jle 0x60bf
movq %rbx, 0xa0(%rsp)
xorl %edi, %edi
movq 0x38(%rsp), %r8
movq 0x40(%rsp), %rbx
xorl %ebp, %ebp
xorl %r12d, %r12d
movl $0x0, 0x14(%rsp)
movq %rdi, 0x58(%rsp)
movq %r8, 0x8(%rsp)
movq %rdi, %r13
shlq $0x10, %r13
subq %rdi, %r13
movq 0x40(%rsp), %rax
leaq (%rax,%r13,2), %rsi
leaq (%rdi,%rdi,2), %rdx
shlq $0x4, %rdx
addq %r15, %rdx
movq 0x70(%rsp), %rdi
movl 0x2c(%rsp), %ecx
callq 0xb704
movq 0x20(%rsp), %rdx
cmpq 0x68(%rsp), %rdx
setbe %cl
cmpq $0xd, %rdx
setb %dl
testl %eax, %eax
sets %sil
orb %cl, %dl
movq 0x58(%rsp), %rdi
cmpq $0x8000, %rdi           # imm = 0x8000
setae %cl
orb %dl, %cl
orb %sil, %cl
jne 0x6062
addl $0xffff, %r13d          # imm = 0xFFFF
xorl %ecx, %ecx
movq 0x8(%rsp), %r8
movzwl (%r8,%rcx,2), %edx
xorl %esi, %esi
cmpw (%rbx,%rcx,2), %dx
setne %sil
addl %esi, %r12d
incq %rcx
leal (%rcx,%rbp), %edx
cmpl %edx, %r13d
jg 0x6043
jmp 0x6067
movq 0x8(%rsp), %r8
addl %eax, 0x14(%rsp)
incq %rdi
addq $0xffff, %rbp           # imm = 0xFFFF
movl $0x1fffe, %eax          # imm = 0x1FFFE
addq %rax, %rbx
addq %rax, %r8
cmpq 0x60(%rsp), %rdi
jne 0x5fcd
movl 0x28(%rsp), %eax
movl %eax, 0x8(%rsp)
movq 0x40(%rsp), %r13
movq 0xa0(%rsp), %rbx
jmp 0x60d7
movl $0x0, 0x8(%rsp)
callq 0x2050
movq %rax, %rbx
movl $0x0, 0x14(%rsp)
xorl %r12d, %r12d
jmp 0x60d7
movl $0x0, 0x14(%rsp)
movl 0x28(%rsp), %eax
movl %eax, 0x8(%rsp)
xorl %r12d, %r12d
movq 0x40(%rsp), %r13
callq 0x2050
subq %rbx, %rax
movabsq $0x431bde82d7b634db, %rcx # imm = 0x431BDE82D7B634DB
imulq %rcx
movq %rdx, %rcx
sarq $0x12, %rcx
movq %rdx, %rax
shrq $0x3f, %rax
addq %rax, %rcx
sarq $0x13, %rdx
addq %rdx, %rax
addq 0xa8(%rsp), %rax
cqto
movq %rcx, %rbp
idivq %rcx
movq %rax, 0x58(%rsp)
movl $0xe, %edx
movq 0xceeb3(%rip), %rdi     # 0xd4fd8
leaq 0x8a7c(%rip), %rsi      # 0xeba8
callq 0x2190
movq 0xceea0(%rip), %rdi     # 0xd4fd8
movq 0x20(%rsp), %rsi
callq 0x2200
movl $0xc, %edx
movq %rax, %rdi
leaq 0x8a66(%rip), %rsi      # 0xebb7
movq %rax, %rbx
callq 0x2190
movq %rbx, %rdi
movl 0x2c(%rsp), %esi
callq 0x2200
movq %rax, %rbx
movl $0x1f, %edx
movq %rax, %rdi
leaq 0x8a4d(%rip), %rsi      # 0xebc4
callq 0x2190
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x2130
movq %rax, %rbp
movl $0xf, %edx
movq %rax, %rdi
leaq 0x89f8(%rip), %rsi      # 0xeb91
callq 0x2190
movq %rbp, %rdi
movq 0x58(%rsp), %rsi
callq 0x2200
movl $0x6, %edx
movq %rax, %rdi
leaq 0x89e7(%rip), %rsi      # 0xeba1
callq 0x2190
movl 0x8(%rsp), %eax
xorl 0x14(%rsp), %eax
orl %r12d, %eax
setne %bl
je 0x6254
movl $0xa, %edx
movq 0xcedf9(%rip), %rdi     # 0xd4fd8
leaq 0x88d3(%rip), %rsi      # 0xeab9
callq 0x2190
movq 0xcede6(%rip), %rdi     # 0xd4fd8
movl 0x8(%rsp), %esi
callq 0x2200
movq %rax, %rbp
movl $0x1a, %edx
movq %rax, %rdi
leaq 0x89d7(%rip), %rsi      # 0xebe4
callq 0x2190
movq %rbp, %rdi
movl 0x14(%rsp), %esi
callq 0x2200
movq %rax, %rbp
movl $0x5, %edx
movq %rax, %rdi
leaq 0x898e(%rip), %rsi      # 0xebbe
callq 0x2190
movq %rbp, %rdi
movl %r12d, %esi
callq 0x2200
movl $0x13, %edx
movq %rax, %rdi
leaq 0x89b0(%rip), %rsi      # 0xebff
callq 0x2190
movq 0xced7d(%rip), %rcx     # 0xd4fd8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x2140
movsbl %al, %esi
movq 0xced5f(%rip), %rdi     # 0xd4fd8
callq 0x2040
movq %rax, %rdi
callq 0x20e0
movq 0x20(%rsp), %rcx
cmpq $0xd, %rcx
setb %al
cmpq 0x68(%rsp), %rcx
setbe %bpl
orb %al, %bpl
testb %bl, %bpl
jne 0x6545
cmpl $0x0, 0x18(%rsp)
jle 0x633b
xorl %eax, %eax
xorl %r12d, %r12d
movq 0x30(%rsp), %rcx
cmpw $0x2, (%r13,%rax)
sbbl $-0x1, %r12d
addq $0x2, %rax
cmpq %rax, %rcx
jne 0x62bc
testl %r12d, %r12d
je 0x633b
movl $0x16, %edx
movq 0xcecf7(%rip), %rdi     # 0xd4fd8
leaq 0x897a(%rip), %rsi      # 0xec62
callq 0x2190
movq 0xcece4(%rip), %rdi     # 0xd4fd8
movl %r12d, %esi
callq 0x2200
movq %rax, %r12
movl $0x7, %edx
movq %rax, %rdi
leaq 0x896b(%rip), %rsi      # 0xec79
callq 0x2190
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x2140
movsbl %al, %esi
movq %r12, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20e0
testb %bl, %bl
jne 0x6478
movq 0x78(%rsp), %rax
movq 0x80(%rsp), %rdx
cmpq %rdx, %rax
je 0x63b8
xorl %esi, %esi
xorl %edi, %edi
xorl %ecx, %ecx
leal 0x1(%rsi), %r9d
movl %esi, %r8d
movzwl (%r13,%r8,2), %r8d
shll %cl, %r8d
movq %r9, %r10
movl $0x80008001, %r11d      # imm = 0x80008001
imulq %r11, %r10
shrq $0x2f, %r10
movl %r10d, %r11d
shll $0x10, %r11d
subl %r11d, %r10d
addl %esi, %r10d
incl %r10d
cmpl $0xff3f, %r10d          # imm = 0xFF3F
jae 0x639a
movl %r9d, %esi
jmp 0x63a0
addl $0xc1, %esi
incl %ecx
orl %r8d, %edi
cmpl $0x8, %ecx
jne 0x635b
movb %dil, (%rax)
shrl $0x8, %edi
incq %rax
cmpq %rdx, %rax
jne 0x6359
movq 0x60(%rsp), %rbx
movq %r13, %r12
cmpl $0x0, 0x18(%rsp)
jle 0x63f0
movq 0x70(%rsp), %rdi
movq %r12, %rsi
leaq 0xb0(%rsp), %rdx
callq 0xb7be
testl %eax, %eax
jne 0x6502
addq $0x1fffe, %r12          # imm = 0x1FFFE
decq %rbx
jne 0x63c7
movq 0x50(%rsp), %rax
movq (%rax), %rdi
movq 0x8(%rax), %rax
movq %rax, %rdx
subq %rdi, %rdx
movq 0x78(%rsp), %rsi
movq 0x80(%rsp), %rcx
subq %rsi, %rcx
cmpq %rcx, %rdx
jne 0x6425
cmpq %rdi, %rax
je 0x6478
callq 0x2180
testl %eax, %eax
je 0x6478
movl $0x3b, %edx
movq 0xceba7(%rip), %rdi     # 0xd4fd8
leaq 0x8849(%rip), %rsi      # 0xec81
callq 0x2190
movq 0xceb94(%rip), %rcx     # 0xd4fd8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x2140
movsbl %al, %esi
movq 0xceb76(%rip), %rdi     # 0xd4fd8
callq 0x2040
movq %rax, %rdi
callq 0x20e0
testb %bpl, %bpl
jne 0x6564
movl 0x2c(%rsp), %eax
incl %eax
cmpl 0x4c(%rsp), %eax
jne 0x5eb6
movq 0x20(%rsp), %rcx
incq %rcx
movl 0x28(%rsp), %eax
addl 0x18(%rsp), %eax
movl %eax, 0x28(%rsp)
incl 0x4c(%rsp)
movq %rcx, 0x20(%rsp)
cmpq $0x19, %rcx
jne 0x5eb4
movq %r15, %rdi
callq 0x21a0
movq %r13, %rdi
callq 0x21a0
movq 0x38(%rsp), %rdi
callq 0x21a0
movq 0x78(%rsp), %rdi
testq %rdi, %rdi
je 0x64e3
movq 0x88(%rsp), %rsi
subq %rdi, %rsi
callq 0x2170
leaq 0xe0(%rsp), %rdi
callq 0x2120
addq $0x1468, %rsp           # imm = 0x1468
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xceacf(%rip), %rdi     # 0xd4fd8
leaq 0x85c9(%rip), %rsi      # 0xead9
movl $0x36, %edx
callq 0x2190
movq 0xceab7(%rip), %rdi     # 0xd4fd8
callq 0x2090
leaq 0x85e3(%rip), %rdi      # 0xeb10
leaq 0x849b(%rip), %rsi      # 0xe9cf
leaq 0x9d92(%rip), %rcx      # 0x102cd
movl $0x133, %edx            # imm = 0x133
callq 0x20c0
leaq 0x86c7(%rip), %rdi      # 0xec13
leaq 0x847c(%rip), %rsi      # 0xe9cf
leaq 0x9d73(%rip), %rcx      # 0x102cd
movl $0x11d, %edx            # imm = 0x11D
callq 0x20c0
leaq 0x8752(%rip), %rdi      # 0xecbd
leaq 0x845d(%rip), %rsi      # 0xe9cf
leaq 0x9d54(%rip), %rcx      # 0x102cd
movl $0x138, %edx            # imm = 0x138
callq 0x20c0
movq 0xcea4e(%rip), %rdi     # 0xd4fd8
leaq 0x8428(%rip), %rsi      # 0xe9b9
callq 0x2150
movq %rax, %rdi
callq 0x2090
leaq 0x8423(%rip), %rdi      # 0xe9c8
leaq 0x8423(%rip), %rsi      # 0xe9cf
leaq 0x9d1a(%rip), %rcx      # 0x102cd
movl $0xbe, %edx
callq 0x20c0
movq 0xcea14(%rip), %rdi     # 0xd4fd8
leaq 0x84d1(%rip), %rsi      # 0xea9c
callq 0x2150
movq %rax, %rdi
callq 0x2090
leaq 0x83e9(%rip), %rdi      # 0xe9c8
leaq 0x83e9(%rip), %rsi      # 0xe9cf
leaq 0x9ce0(%rip), %rcx      # 0x102cd
movl $0xc3, %edx
callq 0x20c0
movl %eax, %ebp
movq 0xce9d8(%rip), %rbx     # 0xd4fd8
leaq 0x84a4(%rip), %rsi      # 0xeaab
movl $0x18, %edx
movq %rbx, %rdi
callq 0x2190
movq %rbx, %rdi
movl $0x12, %esi
callq 0x2200
movq %rax, %rbx
leaq 0x85ca(%rip), %rsi      # 0xebf5
movl $0x9, %edx
movq %rax, %rdi
callq 0x2190
movq %rbx, %rdi
movl %ebp, %esi
callq 0x2200
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2140
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x20e0
leaq 0x8451(%rip), %rdi      # 0xeac4
leaq 0x8355(%rip), %rsi      # 0xe9cf
leaq 0x9c4c(%rip), %rcx      # 0x102cd
movl $0xcf, %edx
callq 0x20c0
movq 0xce946(%rip), %rdi     # 0xd4fd8
leaq 0x8440(%rip), %rsi      # 0xead9
callq 0x2150
movq %rax, %rdi
callq 0x2090
leaq 0x8463(%rip), %rdi      # 0xeb10
leaq 0x831b(%rip), %rsi      # 0xe9cf
leaq 0x9c12(%rip), %rcx      # 0x102cd
movl $0xd3, %edx
callq 0x20c0
movq 0xce90c(%rip), %rdi     # 0xd4fd8
leaq 0x8443(%rip), %rsi      # 0xeb16
callq 0x2150
movq %rax, %rdi
callq 0x2090
leaq 0x82e1(%rip), %rdi      # 0xe9c8
leaq 0x82e1(%rip), %rsi      # 0xe9cf
leaq 0x9bd8(%rip), %rcx      # 0x102cd
movl $0xda, %edx
callq 0x20c0
jmp 0x674c
jmp 0x671a
jmp 0x671a
jmp 0x6707
movq %rax, %rbx
jmp 0x6737
jmp 0x671a
jmp 0x671a
jmp 0x671a
jmp 0x671a
jmp 0x671a
jmp 0x671a
jmp 0x671a
movq %rax, %rbx
movq 0x78(%rsp), %rdi
testq %rdi, %rdi
je 0x6737
movq 0x88(%rsp), %rsi
subq %rdi, %rsi
callq 0x2170
leaq 0xe0(%rsp), %rdi
callq 0x2120
movq %rbx, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x76b9