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

	{
		rs.encode(code);
		bool error = false;
		for (int i = 0; i < rs.N; ++i)
			error |= code[i] != target[i];
		if (error)
			std::cout << "encoder error!" << std::endl;
		assert(!error);
		//print_table(code + rs.K, "parity", NR);
		error = rs.decode(code);
		if (error)
			std::cout << "decoder error!" << std::endl;
		assert(!error);
		// first symbol is without corruption
		int pos = 0, par = 0, corrupt = -1, erasures_count = 0;
		TYPE erasures[NR];
		// need one parity symbol per erasure
		for (int i = 0; pos < rs.N && par+1 <= NR && i < NR/2; ++i, ++corrupt, ++pos, ++par)
			code[erasures[erasures_count++] = pos] ^= pos;
		// need two parity symbols per error
		for (int i = 0; pos < rs.N && par+2 <= NR && i < NR/2; ++i, ++corrupt, ++pos, par+=2)
			code[pos] ^= pos;
		int corrected = rs.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 && rs.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 < rs.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() + M * rs.K - 1) / (M * rs.K);
	TYPE *coded = new TYPE[rs.N * blocks];
	{
		unsigned acc = 0, bit = 0, pos = 0;
		for (unsigned byte : data) {
			acc |= byte << bit;
			bit += 8;
			while (bit >= M) {
				bit -= M;
				coded[pos++] = rs.N & acc;
				acc >>= M;
				if (pos % rs.N >= rs.K)
					pos += NR;
			}
		}
	}
	{
		auto start = std::chrono::system_clock::now();
		for (int i = 0; i < blocks; ++i)
			rs.encode(coded + i * rs.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 = (rs.N * blocks * M) / 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> bit_dist(0, M-1), pos_dist(0, rs.N-1);
	auto rnd_bit = std::bind(bit_dist, generator);
	auto rnd_pos = std::bind(pos_dist, generator);
	std::vector<uint8_t> recovered(data.size());
	TYPE *tmp = new TYPE[rs.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 < rs.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 * rs.N + erasures[i*NR + j]] ^= 1 << rnd_bit();
					++corrupt;
				}
			}
			int corrected = 0, wrong = 0;
			auto start = std::chrono::system_clock::now();
			for (int i = 0; i < blocks; ++i) {
				int result = rs.decode(tmp + i * rs.N, erasures + i * NR, erasures_count);
				if (places > NR/2 && places > erasures_count && result >= 0)
					for (int j = i * rs.N; j < (i + 1) * rs.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 = (rs.N * blocks * M) / 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));
			if (corrupt == corrected && !wrong) {
				unsigned acc = 0, bit = 0, pos = 0;
				for (uint8_t &byte: recovered) {
					while (bit < 8) {
						acc |= (unsigned)tmp[pos++] << bit;
						bit += M;
						if (pos % rs.N >= rs.K)
							pos += NR;
					}
					bit -= 8;
					byte = 255 & acc;
					acc >>= 8;
				}
				for (int i = 0; i < blocks; ++i) {
					TYPE syndromes[NR];
					if (rs.compute_syndromes(tmp + i * rs.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 $0x14d8, %rsp           # imm = 0x14D8
movq %r8, %r13
movq %rcx, %rbx
movq %rdx, %r14
movq %rsi, %rbp
movq %rdi, %r15
movq 0xce6b6(%rip), %r12     # 0xd4fd8
leaq 0x8086(%rip), %rsi      # 0xe9af
movl $0x9, %edx
movq %r12, %rdi
callq 0x2190
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movq %r12, %rdi
movq %rbp, %r12
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 %rbp, %rdi
movq %r14, %rsi
callq 0xca36
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 0x6981
testb $0x1, %cl
jne 0x74ea
movq %r12, %rdi
movq %r14, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0xcbea
testl %eax, %eax
jne 0x7524
movdqa 0x765e(%rip), %xmm0     # 0xe020
xorl %eax, %eax
movdqa 0x7664(%rip), %xmm1     # 0xe030
movdqa %xmm0, 0x150(%rsp,%rax,2)
movdqu (%r14,%rax,2), %xmm2
pxor %xmm0, %xmm2
movdqu %xmm2, (%r14,%rax,2)
addq $0x8, %rax
paddw %xmm1, %xmm0
cmpq $0x20, %rax
jne 0x69cc
movups 0x40(%r14), %xmm0
movups 0x50(%r14), %xmm1
xorps 0x763c(%rip), %xmm0     # 0xe040
movups %xmm0, 0x40(%r14)
xorps 0x7640(%rip), %xmm1     # 0xe050
movups %xmm1, 0x50(%r14)
leaq 0x150(%rsp), %rdx
movq %r12, %rdi
movq %r14, %rsi
movl $0x20, %ecx
callq 0xcbea
cmpl $0x2f, %eax
jne 0x755e
leaq 0xd0(%rsp), %rdx
movq %r12, %rdi
movq %r14, %rsi
callq 0xcc94
testl %eax, %eax
jne 0x75f2
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 0x6a55
testb $0x1, %cl
jne 0x762c
movq (%r13), %r14
movq 0x8(%r13), %r15
movq %r15, %rax
subq %r14, %rax
leaq 0xffbef(,%rax,8), %rax
movabsq $0x401044214c74698f, %rcx # imm = 0x401044214C74698F
mulq %rcx
shrq $0x12, %rdx
movl %edx, %eax
shll $0x10, %eax
subl %edx, %eax
movq %rax, 0x50(%rsp)
cltq
addq %rax, %rax
movq %rdx, 0x10(%rsp)
testl %edx, %edx
movq $-0x1, %rbx
cmovnsq %rax, %rbx
movq %rbx, %rdi
callq 0x2030
movq %rax, 0x38(%rsp)
cmpq %r14, %r15
je 0x6b4a
xorl %r9d, %r9d
movl $0x80008001, %eax       # imm = 0x80008001
xorl %ecx, %ecx
xorl %edi, %edi
movzbl (%r14), %edx
shll %cl, %edx
orl %r9d, %edx
leal 0x8(%rcx), %esi
cmpl $0x8, %ecx
jb 0x6b37
leal 0x1(%rdi), %r8d
movl %edi, %ecx
movq 0x38(%rsp), %r9
movw %dx, (%r9,%rcx,2)
movq %r8, %rcx
imulq %rax, %rcx
shrq $0x2f, %rcx
movl %ecx, %r9d
shll $0x10, %r9d
subl %r9d, %ecx
addl %edi, %ecx
incl %ecx
cmpl $0xffbf, %ecx           # imm = 0xFFBF
jb 0x6b27
addl $0x41, %edi
movl %edi, %r8d
addl $-0x10, %esi
shrl $0x10, %edx
movl %r8d, %edi
cmpl $0xf, %esi
ja 0x6af0
jmp 0x6b3a
movl %edi, %r8d
incq %r14
movl %edx, %r9d
movl %esi, %ecx
movl %r8d, %edi
cmpq %r15, %r14
jne 0x6adf
callq 0x2050
movq %rax, %r14
cmpl $0x0, 0x10(%rsp)
movq %r12, %rbp
jle 0x6b84
movq 0x10(%rsp), %r12
andl $0x7fffffff, %r12d      # imm = 0x7FFFFFFF
movq 0x38(%rsp), %r15
movq %rbp, %rdi
movq %r15, %rsi
callq 0xca36
addq $0x1fffe, %r15          # imm = 0x1FFFE
decq %r12
jne 0x6b6d
movq %rbp, 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
addq %rax, %r14
movq 0x8(%r13), %rcx
subq (%r13), %rcx
sarq $0x13, %rdx
addq %rdx, %rax
addq %rcx, %rax
xorl %edx, %edx
divq %r14
movq %rax, %r15
imull $0xffff0, 0x10(%rsp), %ebp # imm = 0xFFFF0
sarl $0x3, %ebp
movslq %ebp, %rax
movq %rax, 0xa0(%rsp)
subq %rcx, %rax
js 0x6beb
cvtsi2ss %rax, %xmm1
jmp 0x6c00
movq %rax, %rdx
shrq %rdx
andl $0x1, %eax
orq %rdx, %rax
cvtsi2ss %rax, %xmm1
addss %xmm1, %xmm1
mulss 0x73fc(%rip), %xmm1     # 0xe004
testq %rcx, %rcx
js 0x6c14
cvtsi2ss %rcx, %xmm0
jmp 0x6c29
movq %rcx, %rax
shrq %rax
andl $0x1, %ecx
orq %rax, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
divss %xmm0, %xmm1
movss %xmm1, 0x18(%rsp)
movq 0xce39e(%rip), %r12     # 0xd4fd8
leaq 0x7efd(%rip), %rsi      # 0xeb3e
movl $0xc, %edx
movq %r12, %rdi
callq 0x2190
movq 0x8(%r13), %rsi
subq (%r13), %rsi
movq %r12, %rdi
callq 0x20d0
movq %rax, %r12
leaq 0x7ee3(%rip), %rsi      # 0xeb4b
movl $0x13, %edx
movq %rax, %rdi
callq 0x2190
movq %r12, %rdi
movl %ebp, %esi
callq 0x2200
movq %rax, %r12
leaq 0x7ed6(%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 0x18(%rsp), %xmm0
movq %r12, %rdi
callq 0x21d0
movq %rax, %r12
leaq 0x7e99(%rip), %rsi      # 0xeb71
movl $0x11, %edx
movq %rax, %rdi
callq 0x2190
movq %r12, %rdi
movq 0x10(%rsp), %rsi
callq 0x2200
movq %rax, %r12
leaq 0x7e87(%rip), %rsi      # 0xeb83
movl $0xd, %edx
movq %rax, %rdi
callq 0x2190
movq %r12, %rdi
movq %r14, %rsi
callq 0x2130
movq %rax, %r14
leaq 0x7e73(%rip), %rsi      # 0xeb91
movl $0xf, %edx
movq %rax, %rdi
callq 0x2190
movq %r14, %rdi
movl %r15d, %esi
callq 0x2200
movq %rax, %r14
leaq 0x7e61(%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 0x150(%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 $0xf00000000, %rax      # imm = 0xF00000000
movq %rax, 0xc0(%rsp)
movq %rcx, 0xc8(%rsp)
movabsq $0xfffe00000000, %rax   # imm = 0xFFFE00000000
movq %rax, 0xb0(%rsp)
movq %rcx, 0xb8(%rsp)
movq 0x8(%r13), %rsi
subq (%r13), %rsi
leaq 0x78(%rsp), %rdi
leaq 0xd0(%rsp), %rdx
callq 0x296a
movq %rbx, %rdi
callq 0x2030
movq %rax, 0x28(%rsp)
movq 0x10(%rsp), %rbx
movq %r13, 0x90(%rsp)
movl %ebx, %eax
shll $0x6, %eax
cltq
addq %rax, %rax
testl %ebx, %ebx
movq $-0x1, %rdi
cmovnsq %rax, %rdi
callq 0x2030
movq %rax, 0x58(%rsp)
leaq 0xb8(%rsp), %r13
movq 0x50(%rsp), %rax
cmpl $0x2, %eax
movl $0x1, %ecx
movl $0x1, 0x44(%rsp)
cmovll %ecx, %eax
addl %eax, %eax
movq %rax, 0x50(%rsp)
andl $0x7fffffff, %ebx       # imm = 0x7FFFFFFF
movq %rbx, 0x60(%rsp)
movq $0x0, 0x18(%rsp)
leaq 0xb0(%rsp), %r14
movl $0x0, 0x24(%rsp)
xorl %eax, %eax
movl %eax, 0x34(%rsp)
movl %eax, %eax
movq %rax, 0x68(%rsp)
cmpl $0x0, 0x10(%rsp)
jle 0x70a2
movq 0x28(%rsp), %rdi
movq 0x38(%rsp), %rsi
movq 0x50(%rsp), %rdx
callq 0x2100
movq $0x0, 0x8(%rsp)
cmpq $0x0, 0x18(%rsp)
je 0x6f7a
movq 0x8(%rsp), %rbp
movq %rbp, %r15
shlq $0x7, %r15
movq 0x58(%rsp), %rax
leaq (%rax,%r15), %r12
movabsq $0x1ffffff80, %rcx      # imm = 0x1FFFFFF80
andq %rcx, %r15
addq %rax, %r15
leaq (,%rbp,2), %rax
shlq $0x11, %rbp
subq %rax, %rbp
addq 0x28(%rsp), %rbp
xorl %ebx, %ebx
movq %r14, %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x8f9a
movw %ax, (%r15,%rbx,2)
testq %rbx, %rbx
je 0x6f45
xorl %ecx, %ecx
movslq %ecx, %rdx
cmpw %ax, (%r12,%rdx,2)
jne 0x6f3b
movq %r14, %rdi
movq %r13, %rsi
movq %r14, %rdx
callq 0x8f9a
movw %ax, (%r15,%rbx,2)
xorl %ecx, %ecx
jmp 0x6f3d
incl %ecx
movslq %ecx, %rdx
cmpq %rdx, %rbx
jg 0x6f1a
leaq 0xc0(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
movq %rdi, %rdx
callq 0x8f9a
movl $0x1, %edx
movl %eax, %ecx
shll %cl, %edx
movzwl (%r15,%rbx,2), %eax
xorw %dx, (%rbp,%rax,2)
incq %rbx
cmpq 0x18(%rsp), %rbx
jne 0x6f00
movq 0x8(%rsp), %rcx
incq %rcx
movq %rcx, 0x8(%rsp)
cmpq 0x60(%rsp), %rcx
jne 0x6eb9
callq 0x2050
movq %rax, %r12
cmpl $0x0, 0x10(%rsp)
jle 0x70b7
movq %r12, 0x98(%rsp)
xorl %edi, %edi
movq 0x38(%rsp), %r8
movq 0x28(%rsp), %rbp
xorl %r12d, %r12d
xorl %ebx, %ebx
xorl %r15d, %r15d
movq %rdi, 0xa8(%rsp)
movq %r8, 0x48(%rsp)
movl %r15d, 0x8(%rsp)
movq %rdi, %r15
shlq $0x10, %r15
subq %rdi, %r15
movq 0x28(%rsp), %rax
leaq (%rax,%r15,2), %rsi
movq %rdi, %rdx
shlq $0x7, %rdx
addq 0x58(%rsp), %rdx
movq 0x70(%rsp), %rdi
movl 0x34(%rsp), %ecx
callq 0xcbea
movq 0x18(%rsp), %rdx
cmpq 0x68(%rsp), %rdx
setbe %cl
cmpq $0x21, %rdx
setb %dl
testl %eax, %eax
sets %sil
orb %cl, %dl
movq 0xa8(%rsp), %rdi
cmpq $0x8000, %rdi           # imm = 0x8000
setae %cl
orb %dl, %cl
orb %sil, %cl
jne 0x7063
addl $0xffff, %r15d          # imm = 0xFFFF
xorl %ecx, %ecx
movq 0x48(%rsp), %r8
movzwl (%r8,%rcx,2), %edx
xorl %esi, %esi
cmpw (%rbp,%rcx,2), %dx
setne %sil
addl %esi, %ebx
incq %rcx
leal (%rcx,%r12), %edx
cmpl %edx, %r15d
jg 0x7043
jmp 0x7068
movq 0x48(%rsp), %r8
movl 0x8(%rsp), %r15d
addl %eax, %r15d
incq %rdi
addq $0xffff, %r12           # imm = 0xFFFF
movl $0x1fffe, %eax          # imm = 0x1FFFE
addq %rax, %rbp
addq %rax, %r8
cmpq 0x60(%rsp), %rdi
jne 0x6fc1
movl 0x24(%rsp), %eax
movl %eax, 0x8(%rsp)
movq 0x98(%rsp), %r12
jmp 0x70c4
movl $0x0, 0x8(%rsp)
callq 0x2050
movq %rax, %r12
xorl %r15d, %r15d
jmp 0x70c2
xorl %r15d, %r15d
movl 0x24(%rsp), %eax
movl %eax, 0x8(%rsp)
xorl %ebx, %ebx
callq 0x2050
subq %r12, %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 0xa0(%rsp), %rax
cqto
movq %rcx, %rbp
idivq %rcx
movq %rax, 0x48(%rsp)
movl $0xe, %edx
movq 0xcdec6(%rip), %rdi     # 0xd4fd8
leaq 0x7a8f(%rip), %rsi      # 0xeba8
callq 0x2190
movq 0xcdeb3(%rip), %rdi     # 0xd4fd8
movq 0x18(%rsp), %rsi
callq 0x2200
movl $0xc, %edx
movq %rax, %rdi
leaq 0x7a79(%rip), %rsi      # 0xebb7
movq %rax, %r12
callq 0x2190
movq %r12, %rdi
movl 0x34(%rsp), %esi
callq 0x2200
movq %rax, %r12
movl $0x1f, %edx
movq %rax, %rdi
leaq 0x7a60(%rip), %rsi      # 0xebc4
callq 0x2190
movq %r12, %rdi
movq %rbp, %rsi
callq 0x2130
movq %rax, %rbp
movl $0xf, %edx
movq %rax, %rdi
leaq 0x7a0b(%rip), %rsi      # 0xeb91
callq 0x2190
movq %rbp, %rdi
movq 0x48(%rsp), %rsi
callq 0x2200
movl $0x6, %edx
movq %rax, %rdi
leaq 0x79fa(%rip), %rsi      # 0xeba1
callq 0x2190
movl 0x8(%rsp), %eax
xorl %r15d, %eax
orl %ebx, %eax
setne %r12b
je 0x723a
movl $0xa, %edx
movq 0xcde11(%rip), %rdi     # 0xd4fd8
leaq 0x78eb(%rip), %rsi      # 0xeab9
callq 0x2190
movq 0xcddfe(%rip), %rdi     # 0xd4fd8
movl 0x8(%rsp), %esi
callq 0x2200
movq %rax, %rbp
movl $0x1a, %edx
movq %rax, %rdi
leaq 0x79ef(%rip), %rsi      # 0xebe4
callq 0x2190
movq %rbp, %rdi
movl %r15d, %esi
callq 0x2200
movq %rax, %r15
movl $0x5, %edx
movq %rax, %rdi
leaq 0x79a7(%rip), %rsi      # 0xebbe
callq 0x2190
movq %r15, %rdi
movl %ebx, %esi
callq 0x2200
movl $0x13, %edx
movq %rax, %rdi
leaq 0x79ca(%rip), %rsi      # 0xebff
callq 0x2190
movq 0xcdd97(%rip), %rcx     # 0xd4fd8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x2140
movsbl %al, %esi
movq 0xcdd79(%rip), %rdi     # 0xd4fd8
callq 0x2040
movq %rax, %rdi
callq 0x20e0
movq 0x18(%rsp), %rcx
cmpq $0x21, %rcx
setb %al
cmpq 0x68(%rsp), %rcx
setbe %r15b
orb %al, %r15b
movl %r15d, %eax
andb %r12b, %al
cmpb $0x1, %al
je 0x74ac
testb %r12b, %r12b
jne 0x73db
movq 0x78(%rsp), %rax
movq 0x80(%rsp), %rdx
cmpq %rdx, %rax
je 0x7316
xorl %edi, %edi
xorl %ecx, %ecx
xorl %esi, %esi
cmpl $0x7, %ecx
ja 0x7305
leal 0x1(%rdi), %r8d
movl %edi, %r9d
movq 0x28(%rsp), %r10
movzwl (%r10,%r9,2), %r9d
shll %cl, %r9d
movq %r8, %r10
movl $0x80008001, %r11d      # imm = 0x80008001
imulq %r11, %r10
shrq $0x2f, %r10
movl %r10d, %r11d
shll $0x10, %r11d
subl %r11d, %r10d
addl %edi, %r10d
incl %r10d
cmpl $0xffbf, %r10d          # imm = 0xFFBF
jb 0x72fc
addl $0x41, %edi
movl %edi, %r8d
orl $0x10, %ecx
orl %r9d, %esi
movl %r8d, %edi
addl $-0x8, %ecx
movb %sil, (%rax)
shrl $0x8, %esi
incq %rax
cmpq %rdx, %rax
jne 0x72b3
movq 0x60(%rsp), %r12
movq 0x28(%rsp), %rbx
cmpl $0x0, 0x10(%rsp)
jle 0x7350
movq 0x70(%rsp), %rdi
movq %rbx, %rsi
leaq 0xd0(%rsp), %rdx
callq 0xcc94
testl %eax, %eax
jne 0x7469
addq $0x1fffe, %rbx          # imm = 0x1FFFE
decq %r12
jne 0x7327
movq 0x90(%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 0x7388
cmpq %rdi, %rax
je 0x73db
callq 0x2180
testl %eax, %eax
je 0x73db
movl $0x3b, %edx
movq 0xcdc44(%rip), %rdi     # 0xd4fd8
leaq 0x78e6(%rip), %rsi      # 0xec81
callq 0x2190
movq 0xcdc31(%rip), %rcx     # 0xd4fd8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x2140
movsbl %al, %esi
movq 0xcdc13(%rip), %rdi     # 0xd4fd8
callq 0x2040
movq %rax, %rdi
callq 0x20e0
testb %r15b, %r15b
jne 0x74cb
movl 0x34(%rsp), %eax
incl %eax
cmpl 0x44(%rsp), %eax
jne 0x6e86
movq 0x18(%rsp), %rcx
incq %rcx
movl 0x24(%rsp), %eax
addl 0x10(%rsp), %eax
movl %eax, 0x24(%rsp)
incl 0x44(%rsp)
movq %rcx, 0x18(%rsp)
cmpq $0x41, %rcx
jne 0x6e84
movq 0x58(%rsp), %rdi
callq 0x21a0
movq 0x28(%rsp), %rdi
callq 0x21a0
movq 0x38(%rsp), %rdi
callq 0x21a0
movq 0x78(%rsp), %rdi
testq %rdi, %rdi
je 0x744a
movq 0x88(%rsp), %rsi
subq %rdi, %rsi
callq 0x2170
leaq 0x150(%rsp), %rdi
callq 0x2120
addq $0x14d8, %rsp           # imm = 0x14D8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0xcdb68(%rip), %rdi     # 0xd4fd8
leaq 0x7662(%rip), %rsi      # 0xead9
movl $0x36, %edx
callq 0x2190
movq 0xcdb50(%rip), %rdi     # 0xd4fd8
callq 0x2090
leaq 0x767c(%rip), %rdi      # 0xeb10
leaq 0x7534(%rip), %rsi      # 0xe9cf
leaq 0x972b(%rip), %rcx      # 0x10bcd
movl $0xa3, %edx
callq 0x20c0
leaq 0x7760(%rip), %rdi      # 0xec13
leaq 0x7515(%rip), %rsi      # 0xe9cf
leaq 0x970c(%rip), %rcx      # 0x10bcd
movl $0x91, %edx
callq 0x20c0
leaq 0x77eb(%rip), %rdi      # 0xecbd
leaq 0x74f6(%rip), %rsi      # 0xe9cf
leaq 0x96ed(%rip), %rcx      # 0x10bcd
movl $0xa8, %edx
callq 0x20c0
movq 0xcdae7(%rip), %rdi     # 0xd4fd8
leaq 0x74c1(%rip), %rsi      # 0xe9b9
callq 0x2150
movq %rax, %rdi
callq 0x2090
leaq 0x74bc(%rip), %rdi      # 0xe9c8
leaq 0x74bc(%rip), %rsi      # 0xe9cf
leaq 0x96b3(%rip), %rcx      # 0x10bcd
movl $0x2b, %edx
callq 0x20c0
movq 0xcdaad(%rip), %rdi     # 0xd4fd8
leaq 0x756a(%rip), %rsi      # 0xea9c
callq 0x2150
movq %rax, %rdi
callq 0x2090
leaq 0x7482(%rip), %rdi      # 0xe9c8
leaq 0x7482(%rip), %rsi      # 0xe9cf
leaq 0x9679(%rip), %rcx      # 0x10bcd
movl $0x30, %edx
callq 0x20c0
movl %eax, %ebp
movq 0xcda71(%rip), %rbx     # 0xd4fd8
leaq 0x753d(%rip), %rsi      # 0xeaab
movl $0x18, %edx
movq %rbx, %rdi
callq 0x2190
movq %rbx, %rdi
movl $0x2f, %esi
callq 0x2200
movq %rax, %rbx
leaq 0x7663(%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 0x74ea(%rip), %rdi      # 0xeac4
leaq 0x73ee(%rip), %rsi      # 0xe9cf
leaq 0x95e5(%rip), %rcx      # 0x10bcd
movl $0x3d, %edx
callq 0x20c0
movq 0xcd9df(%rip), %rdi     # 0xd4fd8
leaq 0x74d9(%rip), %rsi      # 0xead9
callq 0x2150
movq %rax, %rdi
callq 0x2090
leaq 0x74fc(%rip), %rdi      # 0xeb10
leaq 0x73b4(%rip), %rsi      # 0xe9cf
leaq 0x95ab(%rip), %rcx      # 0x10bcd
movl $0x41, %edx
callq 0x20c0
movq 0xcd9a5(%rip), %rdi     # 0xd4fd8
leaq 0x74dc(%rip), %rsi      # 0xeb16
callq 0x2150
movq %rax, %rdi
callq 0x2090
leaq 0x737a(%rip), %rdi      # 0xe9c8
leaq 0x737a(%rip), %rsi      # 0xe9cf
leaq 0x9571(%rip), %rcx      # 0x10bcd
movl $0x48, %edx
callq 0x20c0
jmp 0x76b1
jmp 0x767f
jmp 0x767f
jmp 0x766e
movq %rax, %rbx
jmp 0x769c
jmp 0x767f
jmp 0x767f
jmp 0x767f
jmp 0x767f
jmp 0x767f
jmp 0x767f
movq %rax, %rbx
movq 0x78(%rsp), %rdi
testq %rdi, %rdi
je 0x769c
movq 0x88(%rsp), %rsi
subq %rdi, %rsi
callq 0x2170
leaq 0x150(%rsp), %rdi
callq 0x2120
movq %rbx, %rdi
callq 0x2210
movq %rax, %rdi
callq 0x76b9