// File: /workspace/github_cpp_makefile_star2_O2/ksherlock[P]wdc-utils/link.cpp
// Function: one_module(std::vector<unsigned char, std::allocator<unsigned char>> const&, std::vector<unsigned char, std::allocator<unsigned char>> const&, std::vector<unsigned char, std::allocator<unsigned char>> const&, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>*)
void one_module(const std::vector<uint8_t> &data, 
	const std::vector<uint8_t> &section_data, 
	const std::vector<uint8_t> &symbol_data,
	std::set<std::string> *local_undefined = nullptr) {

	std::array<int, 256> remap_section;


	std::fill(remap_section.begin(), remap_section.end(), -1);
	remap_section[SECT_PAGE0] = SECT_PAGE0;
	remap_section[SECT_CODE] = SECT_CODE;
	remap_section[SECT_KDATA] = SECT_KDATA;
	remap_section[SECT_DATA] = SECT_DATA;
	remap_section[SECT_UDATA] = SECT_UDATA;

	std::vector<section> local_sections = read_sections(section_data);
	std::vector<symbol> local_symbols = read_symbols(symbol_data);



	// convert local sections to global 
	for (auto &s : local_sections) {
		//printf("section %20s %d\n", s.name.c_str(), s.number);

		if (s.number <= SECT_UDATA) {
			sections[s.number].size += s.size; // for page0 / udata sections.
			continue;
		}


		// todo -- should install section name as global symbol?

		auto iter = section_map.find(s.name);
		if (iter == section_map.end()) {

			int virtual_section = sections.size();
			remap_section[s.number] = virtual_section;
			s.number = virtual_section;

			if (!(s.flags & SEC_NONAME)) {
				/* generate an _BEG_name_ and _END_name */

				symbol sym;

				sym.name = "_BEG_" + s.name;
				upper_case(sym.name);
				sym.section = virtual_section;
				sym.type = S_REL; // check if section has offset?
				sym.flags = SF_DEF | SF_GBL;


				auto iter = symbol_map.find(sym.name);
				if (iter == symbol_map.end()) {
					symbol_map.emplace(sym.name, symbols.size());
					symbols.emplace_back(std::move(sym));
				} else {
					// duplicate label error...
				}


/*
				// add entry for name? or handle via undefined symbol lookup below?
				handled at end if symbol undeinfed.

				sym.name = s.name;
				sym.section = virtual_section;
				sym.type = S_REL;
				sym.flags = SF_DEF | SF_GBL;

				iter = symbol_map.find(sym.name);
				if (iter == symbol_map.end()) {
					symbol_map.emplace(sym.name, symbols.size());
					symbols.emplace_back(std::move(sym));
				} else {
					// duplicate label error...
				}
*/

				sym.name = "_END_" + s.name;
				upper_case(sym.name);

				sym.section = symbols.size();
				sym.type = S_UND;
				sym.flags = 0;

				iter = symbol_map.find(sym.name);
				if (iter == symbol_map.end()) {
					s.end_symbol = sym.section;
					symbol_map.emplace(sym.name, sym.section);
					symbols.emplace_back(std::move(sym));	
				} else {
					// duplicate label...
				}



			}

			sections.emplace_back(s);
			section_map.emplace(s.name, virtual_section);

		} else {
			auto &ss = sections[iter->second];
			assert(ss.flags == s.flags); // check org????
			remap_section[s.number] = iter->second;
			s.number = iter->second;

			// update size (for ref-only sections)
			ss.size += s.size;
		}
	}



	// convert local symbols to global.
	for (auto &s : local_symbols) {

		if (flags.v) {
			const char *status = "";
			if (s.type == S_UND) status = "extern";
			else if (s.flags & SF_GBL) status = "public";
			else status = "private";
			fprintf(stderr, "  %-20s [%s]\n", s.name.c_str(), status);
		}

		if (s.type == S_UND) {


			auto iter = symbol_map.find(s.name);
			if (iter == symbol_map.end()) {
				s.section = symbols.size();
				symbol_map.emplace(s.name, s.section);
				symbols.emplace_back(s);
				undefined_symbols.emplace(s.name);

				fprintf(stderr, "Adding %s to undefined symbols\n", s.name.c_str());
			}
			else {
				// already exists... 
				const auto &ss = symbols[iter->second];
				/* if (ss.type != S_UND) */
				// always copy over since s.section is a big deal.
				s = ss;
			}

			if (local_undefined) {
				if (s.type == S_UND) local_undefined->emplace(s.name);
			}
			continue;
		}

		// remap and fudge the offset.
		if ((s.type & 0x0f) == S_REL) {
			int virtual_section = remap_section[s.section];
			assert(virtual_section != -1);
			s.section = virtual_section;
			s.offset += sections[virtual_section].data.size();
		} else {
			s.section = -1;
		}



		constexpr const unsigned mask = SF_GBL | SF_DEF;
		if ((s.flags & mask) == mask) {

			auto iter = symbol_map.find(s.name);

			if (iter == symbol_map.end()) {
				unsigned tmp = symbols.size();
				symbol_map.emplace(s.name, tmp);
				symbols.emplace_back(s);
			} else {
				auto &ss = symbols[iter->second];

				// if it was undefined, define it!
				if (ss.type == S_UND) {
					ss = s;
					undefined_symbols.erase(s.name);
				}
				else {
					// ok if symbols are identical..
					if (ss.type != s.type || ss.flags != s.flags || ss.section != s.section || ss.offset != s.offset) {
						warnx("Duplicate label %s", s.name.c_str());
						flags.errors++;
					} 
				}
			}

		}

	}

	// set it here. sections may be resized above.
	int current_section = SECT_CODE;
	std::vector<uint8_t> *data_ptr = &sections[current_section].data;


	auto iter = data.begin();
	for(;;) {
		uint8_t op = read_8(iter);
		if (op == REC_END) return;

		if (op < 0xf0) {
			data_ptr->insert(data_ptr->end(), iter, iter + op);
			iter += op;
			continue;
		}

		switch(op) {
			case REC_SPACE: {
				uint16_t count = read_16(iter);
				data_ptr->insert(data_ptr->end(), count, 0);
				break;
			}

			case REC_SECT: {
				/* switch sections */
				uint8_t s = read_8(iter);
				current_section = remap_section[s];
				assert(current_section > 0 && current_section < sections.size());

				data_ptr = &sections[current_section].data;
				break;
			}

			case REC_ORG: {
				assert(!"ORG not supported.");
				break;
			}

			case REC_RELEXP:
			case REC_EXPR: {

				expression e;
				e.relative = op == REC_RELEXP;
				e.section = current_section;

				e.offset =  data_ptr->size();
				e.size = read_8(iter);


				data_ptr->insert(data_ptr->end(), e.size, 0);

				int reduced_size = 0;
				/**/
				for(;;) {
					op = read_8(iter);
					if (op == OP_END) break;

					switch(op) {
						case OP_VAL: {
							reduced_size++;
							uint32_t offset = read_32(iter);
							e.stack.emplace_back(op, offset);
							break;
						}
						case OP_SYM: {
							reduced_size++;
							uint16_t symbol = read_16(iter);
							assert(symbol < local_symbols.size());
							auto &s = local_symbols[symbol];
							switch (s.type & 0x0f) {
								case S_UND:
									// S_UND indicates it's still undefined globally.
									e.stack.emplace_back(OP_SYM, 0, s.section); /* section is actually a symbol number */
									e.undefined = true;
									break;

								case S_REL:
									e.stack.emplace_back(OP_LOC, s.offset, s.section);
									break;

								case S_ABS:
									e.stack.emplace_back(OP_VAL, s.offset);
									break;

								default:
									assert(!"unsupported symbol flags.");
							}
							break;
						}
						case OP_LOC: {
							reduced_size++;
							uint8_t section = read_8(iter);
							uint32_t offset = read_32(iter);
							int real_section = remap_section[section];
							assert(real_section >= 0);
							e.stack.emplace_back(op, offset, real_section);
							break;
						}
						// operations..
						//unary
						case OP_NOT:
						case OP_NEG:
						case OP_FLP:
							e.stack.emplace_back(op);
							break;
						// binary
						case OP_EXP:
						case OP_MUL:
						case OP_DIV:
						case OP_MOD:
						case OP_SHR:
						case OP_SHL:
						case OP_ADD:
						case OP_SUB:
						case OP_AND:
						case OP_OR:
						case OP_XOR:
						case OP_EQ:
						case OP_GT:
						case OP_LT:
						case OP_UGT:
						case OP_ULT:
							reduced_size--;
							e.stack.emplace_back(op);
							break;
						default:
							assert(!"unsupported expression opcode.");
					}
				}

				if (reduced_size != 1) {
					expr_error(true, e, "Malformed expression");
				}
				sections[current_section].expressions.emplace_back(std::move(e));
				break;
			}


			case REC_LINE: break;
			case REC_DEBUG: {
				uint16_t size = read_16(iter);
				iter += size;
				break;		
			}

		}
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x4b8, %rsp            # imm = 0x4B8
movq %rdx, %rbx
movq %rdi, 0x40(%rsp)
xorl %eax, %eax
cmpq $0x400, %rax            # imm = 0x400
je 0x2b9b
orl $-0x1, 0xb0(%rsp,%rax)
addq $0x4, %rax
jmp 0x2b85
movq %rcx, 0x8(%rsp)
movaps 0xa469(%rip), %xmm0     # 0xd010
movaps %xmm0, 0xb0(%rsp)
movl $0x4, 0xc0(%rsp)
leaq 0x98(%rsp), %rdi
callq 0x2806
leaq 0x78(%rsp), %rdi
movq %rbx, %rsi
callq 0x2935
movq 0x98(%rsp), %r14
movq 0xa0(%rsp), %r15
leaq 0x38(%rsp), %rbx
leaq 0x126e8(%rip), %r13     # 0x152d8
leaq 0x48(%rsp), %r12
leaq 0x10(%rsp), %rbp
cmpq %r15, %r14
je 0x2e15
movl 0x2c(%r14), %eax
cmpq $0x4, %rax
ja 0x2c25
movl 0x28(%r14), %ecx
movq 0x126f8(%rip), %rdx     # 0x15310
imulq $0x68, %rax, %rax
addl %ecx, 0x28(%rdx,%rax)
jmp 0x2e0c
movq %r13, %rdi
movq %r14, %rsi
callq 0x6fbc
testq %rax, %rax
je 0x2c71
movslq 0x28(%rax), %rcx
movq 0x126d0(%rip), %rax     # 0x15310
imulq $0x68, %rcx, %rdx
movb 0x20(%rax,%rdx), %sil
cmpb 0x20(%r14), %sil
jne 0x374c
addq %rdx, %rax
movl 0x2c(%r14), %edx
movl %ecx, 0xb0(%rsp,%rdx,4)
movl %ecx, 0x2c(%r14)
movl 0x28(%r14), %ecx
addl %ecx, 0x28(%rax)
jmp 0x2e0c
movq 0x126a0(%rip), %rax     # 0x15318
subq 0x12691(%rip), %rax     # 0x15310
cqto
pushq $0x68
popq %rcx
idivq %rcx
movl %eax, 0x4(%rsp)
movl 0x2c(%r14), %ecx
movl %eax, 0xb0(%rsp,%rcx,4)
movl %eax, 0x2c(%r14)
testb $0x40, 0x20(%r14)
jne 0x2ded
leaq 0x20(%rsp), %rax
movq %rax, 0x10(%rsp)
andq $0x0, 0x18(%rsp)
movb $0x0, 0x20(%rsp)
andw $0x0, 0x30(%rsp)
movabsq $-0x100000000, %rax     # imm = 0xFFFFFFFF00000000
movq %rax, 0x34(%rsp)
movq %r12, %rdi
leaq 0xa48b(%rip), %rsi      # 0xd164
movq %r14, %rdx
callq 0x53d1
movq %rbp, %rdi
movq %r12, %rsi
callq 0x22d0
movq %r12, %rdi
callq 0x2130
movq %rbp, %rdi
callq 0x2b2e
movl 0x4(%rsp), %eax
movl %eax, 0x38(%rsp)
movw $0x302, 0x30(%rsp)      # imm = 0x302
leaq 0x12616(%rip), %rdi     # 0x15328
movq %rbp, %rsi
callq 0x6fbc
testq %rax, %rax
jne 0x2d5b
movq 0x12642(%rip), %rax     # 0x15368
subq 0x12633(%rip), %rax     # 0x15360
cqto
pushq $0x30
popq %rcx
idivq %rcx
movq %rax, 0x48(%rsp)
leaq 0x125e7(%rip), %rdi     # 0x15328
movq %rbp, %rsi
movq %r12, %rdx
callq 0x70de
leaq 0x1260d(%rip), %rdi     # 0x15360
movq %rbp, %rsi
callq 0x5368
movq %r12, %rdi
leaq 0xa405(%rip), %rsi      # 0xd16a
movq %r14, %rdx
callq 0x53d1
movq %rbp, %rdi
movq %r12, %rsi
callq 0x22d0
movq %r12, %rdi
callq 0x2130
movq %rbp, %rdi
callq 0x2b2e
movq 0x125d9(%rip), %rax     # 0x15368
subq 0x125ca(%rip), %rax     # 0x15360
cqto
pushq $0x30
popq %rcx
idivq %rcx
movl %eax, 0x38(%rsp)
andw $0x0, 0x30(%rsp)
leaq 0x12579(%rip), %rdi     # 0x15328
movq %rbp, %rsi
callq 0x6fbc
testq %rax, %rax
jne 0x2de5
movl 0x38(%rsp), %eax
movl %eax, 0x60(%r14)
leaq 0x1255d(%rip), %rdi     # 0x15328
movq %rbp, %rsi
movq %rbx, %rdx
callq 0x745e
leaq 0x12583(%rip), %rdi     # 0x15360
movq %rbp, %rsi
callq 0x5368
movq %rbp, %rdi
callq 0x2130
leaq 0x1251c(%rip), %rdi     # 0x15310
movq %r14, %rsi
callq 0x5448
movq %r13, %rdi
movq %r14, %rsi
leaq 0x4(%rsp), %rdx
callq 0x745e
addq $0x68, %r14
jmp 0x2bfa
movq 0x78(%rsp), %r12
movq 0x80(%rsp), %r14
addq $0x28, %r12
leaq 0xa3f1(%rip), %r15      # 0xd21e
leaq 0x124f4(%rip), %rbp     # 0x15328
movq 0x8(%rsp), %rbx
leaq -0x28(%r12), %r13
cmpq %r14, %r13
je 0x306e
cmpb $0x1, 0x12422(%rip)     # 0x15270
je 0x2fc3
movb -0x8(%r12), %al
testb %al, %al
je 0x2e9b
andb $0xf, %al
cmpb $0x2, %al
jne 0x2eeb
movslq (%r12), %rax
movslq 0xb0(%rsp,%rax,4), %rax
cmpq $-0x1, %rax
je 0x376b
movl %eax, (%r12)
movq 0x12488(%rip), %rcx     # 0x15310
imulq $0x68, %rax, %rax
movl 0x38(%rcx,%rax), %edx
subl 0x30(%rcx,%rax), %edx
addl %edx, -0x4(%r12)
jmp 0x2ef0
movq %rbp, %rdi
movq %r13, %rsi
callq 0x6fbc
testq %rax, %rax
je 0x3007
movslq 0x28(%rax), %rax
imulq $0x30, %rax, %rsi
addq 0x124a2(%rip), %rsi     # 0x15360
movq %r13, %rdi
callq 0x54c0
testq %rbx, %rbx
je 0x2fba
cmpb $0x0, -0x8(%r12)
jne 0x2fba
movq %rbx, %rdi
movq %r13, %rsi
callq 0x7af6
jmp 0x2fba
orl $-0x1, (%r12)
movb -0x7(%r12), %al
notb %al
testb $0x3, %al
jne 0x2fba
movq %rbp, %rdi
movq %r13, %rsi
callq 0x6fbc
testq %rax, %rax
je 0x2f68
movslq 0x28(%rax), %rax
movq 0x12446(%rip), %rcx     # 0x15360
imulq $0x30, %rax, %rax
leaq (%rcx,%rax), %rdi
movb 0x20(%rcx,%rax), %al
testb %al, %al
je 0x2fa3
cmpb -0x8(%r12), %al
jne 0x2f4e
movb 0x21(%rdi), %al
cmpb -0x7(%r12), %al
jne 0x2f4e
movl 0x28(%rdi), %eax
cmpl (%r12), %eax
jne 0x2f4e
movl 0x24(%rdi), %eax
cmpl -0x4(%r12), %eax
je 0x2fba
movq (%r13), %rsi
leaq 0xa311(%rip), %rdi      # 0xd26a
xorl %eax, %eax
callq 0x2280
incl 0x12362(%rip)           # 0x152c8
jmp 0x2fba
movq 0x123f9(%rip), %rax     # 0x15368
subq 0x123ea(%rip), %rax     # 0x15360
cqto
pushq $0x30
popq %rcx
idivq %rcx
movl %eax, 0x10(%rsp)
movq %rbp, %rdi
movq %r13, %rsi
leaq 0x10(%rsp), %rdx
callq 0x7d10
leaq 0x123c7(%rip), %rdi     # 0x15360
movq %r13, %rsi
callq 0x5484
jmp 0x2fba
movq %r13, %rsi
callq 0x54c0
leaq 0x123c6(%rip), %rdi     # 0x15378
movq %r13, %rsi
callq 0x7e3a
addq $0x30, %r12
jmp 0x2e39
testb $0x1, -0x7(%r12)
leaq 0xa247(%rip), %rcx      # 0xd217
cmoveq %r15, %rcx
cmpb $0x0, -0x8(%r12)
leaq 0xa22f(%rip), %rax      # 0xd210
cmoveq %rax, %rcx
movq 0x11fec(%rip), %rax     # 0x14fd8
movq (%rax), %rdi
movq -0x28(%r12), %rdx
leaq 0xa22b(%rip), %rsi      # 0xd226
xorl %eax, %eax
callq 0x2320
jmp 0x2e54
movq 0x1235a(%rip), %rax     # 0x15368
subq 0x1234b(%rip), %rax     # 0x15360
cqto
pushq $0x30
popq %rcx
idivq %rcx
movl %eax, (%r12)
movq %rbp, %rdi
movq %r13, %rsi
movq %r12, %rdx
callq 0x745e
leaq 0x1232a(%rip), %rdi     # 0x15360
movq %r13, %rsi
callq 0x5484
leaq 0x12333(%rip), %rdi     # 0x15378
movq %r13, %rsi
callq 0x7af6
movq 0x11f84(%rip), %rax     # 0x14fd8
movq (%rax), %rdi
movq (%r13), %rdx
leaq 0xa1d2(%rip), %rsi      # 0xd234
xorl %eax, %eax
callq 0x2320
jmp 0x2ec6
movl $0x98, %ebp
addq 0x12296(%rip), %rbp     # 0x15310
movq 0x40(%rsp), %rax
movq (%rax), %rax
leaq 0x48(%rsp), %rcx
movq %rax, (%rcx)
pushq $0x1
popq %rcx
leaq 0x9f9c(%rip), %rbx      # 0xd030
leaq 0x9fad(%rip), %r15      # 0xd048
leaq 0x10(%rsp), %r14
leaq 0x3(%rsp), %r12
movq %rcx, 0x68(%rsp)
leaq 0x20(%rsp), %r13
movzbl (%rax), %ecx
leaq 0x1(%rax), %rdx
movq %rdx, 0x48(%rsp)
movb %cl, 0x3(%rsp)
testq %rcx, %rcx
je 0x36a7
cmpb $-0x11, %cl
ja 0x30eb
movq 0x8(%rbp), %rsi
addq %rdx, %rcx
movq %rbp, %rdi
callq 0x54ea
movzbl 0x3(%rsp), %eax
addq %rax, 0x48(%rsp)
jmp 0x369d
leal -0xf0(%rcx), %edx
cmpl $0x5, %edx
ja 0x369d
movslq (%rbx,%rdx,4), %rdx
addq %rbx, %rdx
jmpq *%rdx
andq $0x0, 0x10(%r13)
xorps %xmm0, %xmm0
movups %xmm0, (%r13)
andl $0x0, 0x17(%rsp)
andq $0x0, 0x10(%rsp)
cmpl $0xf4, %ecx
sete 0x19(%rsp)
movq 0x68(%rsp), %rcx
movl %ecx, 0x10(%rsp)
movq 0x8(%rbp), %rsi
movl (%rbp), %ecx
movl %esi, %edx
subl %ecx, %edx
movl %edx, 0x14(%rsp)
movzbl 0x1(%rax), %edx
addq $0x2, %rax
movq %rax, 0x48(%rsp)
movb %dl, 0x18(%rsp)
movb $0x0, 0x4(%rsp)
movq %rbp, 0x90(%rsp)
movq %rbp, %rdi
leaq 0x4(%rsp), %rcx
callq 0x550a
xorl %ebp, %ebp
movq 0x48(%rsp), %rax
movzbl (%rax), %ecx
leaq 0x1(%rax), %rdx
movq %rdx, 0x48(%rsp)
movb %cl, 0x3(%rsp)
cmpq $0x23, %rcx
ja 0x36d0
movslq (%r15,%rcx,4), %rcx
addq %r15, %rcx
jmpq *%rcx
decl %ebp
movq %r13, %rdi
movq %r12, %rsi
callq 0x55b2
jmp 0x316b
movq %r13, %rdi
movq %r12, %rsi
callq 0x55b2
jmp 0x316b
leaq 0x48(%rsp), %rdi
callq 0x5257
movl %eax, 0x4(%rsp)
movq %r13, %rdi
movq %r12, %rsi
leaq 0x4(%rsp), %rdx
callq 0x552a
jmp 0x32aa
movzbl 0x1(%rax), %edx
leaq 0x2(%rax), %rcx
movq %rcx, 0x48(%rsp)
movzbl 0x2(%rax), %ecx
shll $0x8, %ecx
orq %rdx, %rcx
addq $0x3, %rax
movq %rax, 0x48(%rsp)
movq 0x78(%rsp), %rsi
movq 0x80(%rsp), %rax
subq %rsi, %rax
cqto
pushq $0x30
popq %rdi
idivq %rdi
cmpq %rcx, %rax
jbe 0x36ef
incl %ebp
imulq $0x30, %rcx, %rax
leaq (%rsi,%rax), %rbx
movzbl 0x20(%rsi,%rax), %eax
andl $0xf, %eax
cmpl $0x2, %eax
je 0x32d2
cmpl $0x1, %eax
je 0x32b1
testl %eax, %eax
jne 0x372d
movq 0x28(%rsp), %r14
cmpq 0x30(%rsp), %r14
je 0x34ba
movl 0x28(%rbx), %eax
movq $0x1, (%r14)
movl %eax, 0x8(%r14)
addq $0xc, %r14
movq %r14, 0x28(%rsp)
jmp 0x3590
movzbl 0x1(%rax), %ebx
addq $0x2, %rax
movq %rax, 0x48(%rsp)
leaq 0x48(%rsp), %rdi
callq 0x5257
movl %eax, 0x4(%rsp)
movl 0xb0(%rsp,%rbx,4), %eax
movl %eax, 0x74(%rsp)
testl %eax, %eax
js 0x370e
movq %r13, %rdi
movq %r12, %rsi
leaq 0x4(%rsp), %rdx
leaq 0x74(%rsp), %rcx
callq 0x556c
incl %ebp
jmp 0x316b
movq 0x28(%rsp), %r14
cmpq 0x30(%rsp), %r14
je 0x32ff
movl 0x24(%rbx), %eax
movl $0x2, (%r14)
movl %eax, 0x4(%r14)
andl $0x0, 0x8(%r14)
jmp 0x32f1
movq 0x28(%rsp), %r14
cmpq 0x30(%rsp), %r14
je 0x33de
movq 0x24(%rbx), %rax
movl $0x3, (%r14)
movq %rax, 0x4(%r14)
addq $0xc, %r14
movq %r14, 0x28(%rsp)
jmp 0x316b
movq %r13, %rdi
pushq $0x1
popq %rsi
leaq 0xa5d3(%rip), %rdx      # 0xd8df
callq 0x8474
movq %rax, 0x8(%rsp)
movq 0x20(%rsp), %r12
movq 0x28(%rsp), %r13
leaq 0x20(%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x7974
movq %rax, %r8
movq %r14, %rax
subq %r12, %rax
movl 0x24(%rbx), %ecx
movl $0x2, (%r8,%rax)
movl %ecx, 0x4(%r8,%rax)
andl $0x0, 0x8(%r8,%rax)
leaq 0xc(%r8), %rbx
movq %r12, %rax
movq %r8, %rcx
cmpq %r14, %rax
je 0x338c
movl 0x8(%rax), %edx
movl %edx, 0x8(%rcx)
movq (%rax), %rdx
movq %rdx, (%rcx)
addq $0xc, %rax
addq $0xc, %rcx
addq $0xc, %rbx
jmp 0x3358
movl 0x8(%r14), %eax
movl %eax, 0x8(%rbx)
movq (%r14), %rax
movq %rax, (%rbx)
addq $0xc, %r14
addq $0xc, %rbx
cmpq %r13, %r14
jne 0x3377
movq 0x30(%rsp), %rax
subq %r12, %rax
cqto
pushq $0xc
popq %rcx
idivq %rcx
leaq 0x20(%rsp), %rdi
movq %r8, %r14
movq %r12, %rsi
movq %rax, %rdx
callq 0x6932
movq %r14, %rcx
movq %r14, 0x20(%rsp)
movq %rbx, 0x28(%rsp)
imulq $0xc, 0x8(%rsp), %rax
addq %rax, %rcx
movq %rcx, 0x30(%rsp)
leaq 0x20(%rsp), %r13
leaq 0x3(%rsp), %r12
jmp 0x316b
movq %r13, %rdi
pushq $0x1
popq %rsi
leaq 0xa4f4(%rip), %rdx      # 0xd8df
callq 0x8474
movq %rax, 0x8(%rsp)
movq 0x20(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x28(%rsp), %r13
leaq 0x20(%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x7974
movq %rax, %r8
movq %r14, %rax
movq 0x40(%rsp), %rsi
subq %rsi, %rax
movq 0x24(%rbx), %rcx
movl $0x3, (%r8,%rax)
movq %rcx, 0x4(%r8,%rax)
leaq 0xc(%r8), %rbx
movq %rsi, %rax
movq %r8, %rcx
cmpq %r14, %rax
je 0x3470
movl 0x8(%rax), %edx
movl %edx, 0x8(%rcx)
movq (%rax), %rdx
movq %rdx, (%rcx)
addq $0xc, %rax
addq $0xc, %rcx
addq $0xc, %rbx
jmp 0x343c
movl 0x8(%r14), %eax
movl %eax, 0x8(%rbx)
movq (%r14), %rax
movq %rax, (%rbx)
addq $0xc, %r14
addq $0xc, %rbx
cmpq %r13, %r14
jne 0x345b
movq 0x30(%rsp), %rax
subq %rsi, %rax
cqto
pushq $0xc
popq %rcx
idivq %rcx
leaq 0x20(%rsp), %rdi
movq %r8, %r14
movq %rax, %rdx
callq 0x6932
movq %r14, %rcx
movq %r14, 0x20(%rsp)
movq %rbx, 0x28(%rsp)
imulq $0xc, 0x8(%rsp), %rax
addq %rax, %rcx
movq %rcx, 0x30(%rsp)
leaq 0x20(%rsp), %r13
jmp 0x316b
movq %r13, %rdi
pushq $0x1
popq %rsi
leaq 0xa418(%rip), %rdx      # 0xd8df
callq 0x8474
movq %rax, 0x8(%rsp)
movq 0x20(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x28(%rsp), %r13
leaq 0x20(%rsp), %rdi
movq 0x8(%rsp), %rsi
callq 0x7974
movq %rax, %r8
movq %r14, %rax
movq 0x40(%rsp), %rsi
subq %rsi, %rax
movl 0x28(%rbx), %ecx
movq $0x1, (%r8,%rax)
movl %ecx, 0x8(%r8,%rax)
leaq 0xc(%r8), %rbx
movq %rsi, %rax
movq %r8, %rcx
cmpq %r14, %rax
je 0x354b
movl 0x8(%rax), %edx
movl %edx, 0x8(%rcx)
movq (%rax), %rdx
movq %rdx, (%rcx)
addq $0xc, %rax
addq $0xc, %rcx
addq $0xc, %rbx
jmp 0x3517
movl 0x8(%r14), %eax
movl %eax, 0x8(%rbx)
movq (%r14), %rax
movq %rax, (%rbx)
addq $0xc, %r14
addq $0xc, %rbx
cmpq %r13, %r14
jne 0x3536
movq 0x30(%rsp), %rax
subq %rsi, %rax
cqto
pushq $0xc
popq %rcx
idivq %rcx
leaq 0x20(%rsp), %rdi
movq %r8, %r14
movq %rax, %rdx
callq 0x6932
movq %r14, %rcx
movq %r14, 0x20(%rsp)
movq %rbx, 0x28(%rsp)
imulq $0xc, 0x8(%rsp), %rax
addq %rax, %rcx
movq %rcx, 0x30(%rsp)
leaq 0x20(%rsp), %r13
movb $0x1, 0x1a(%rsp)
jmp 0x316b
cmpl $0x1, %ebp
leaq 0x10(%rsp), %r14
je 0x35b6
pushq $0x1
popq %rdi
movq %r14, %rsi
leaq 0x9d8a(%rip), %rdx      # 0xd33b
callq 0x55ec
movl 0x68(%rsp), %eax
movq 0x11d4f(%rip), %rcx     # 0x15310
imulq $0x68, %rax, %rax
leaq (%rcx,%rax), %rdi
addq $0x48, %rdi
movq %r14, %rsi
callq 0x5f36
movq %r13, %rdi
callq 0x690c
leaq 0x9a4c(%rip), %rbx      # 0xd030
movq 0x90(%rsp), %rbp
jmp 0x369d
movzbl 0x1(%rax), %ecx
addq $0x2, %rax
movq %rax, 0x48(%rsp)
movslq 0xb0(%rsp,%rcx,4), %rdi
testq %rdi, %rdi
jle 0x378a
movq 0x11d02(%rip), %rax     # 0x15318
movq 0x11cf3(%rip), %rcx     # 0x15310
subq %rcx, %rax
cqto
pushq $0x68
popq %rsi
idivq %rsi
cmpq %rdi, %rax
jbe 0x378a
movq %rdi, 0x68(%rsp)
imulq $0x68, %rdi, %rax
leaq (%rcx,%rax), %rbp
addq $0x30, %rbp
jmp 0x369d
movzbl 0x1(%rax), %ecx
leaq 0x2(%rax), %rdx
movq %rdx, 0x48(%rsp)
movzbl 0x2(%rax), %edx
shll $0x8, %edx
orq %rcx, %rdx
addq %rdx, %rax
addq $0x3, %rax
movq %rax, 0x48(%rsp)
jmp 0x369d
movzbl 0x1(%rax), %ecx
leaq 0x2(%rax), %rdx
movq %rdx, 0x48(%rsp)
movzbl 0x2(%rax), %edx
shll $0x8, %edx
orq %rcx, %rdx
addq $0x3, %rax
movq %rax, 0x48(%rsp)
movq 0x8(%rbp), %rsi
movb $0x0, 0x10(%rsp)
movq %rbp, %rdi
movq %r14, %rcx
callq 0x550a
movq 0x48(%rsp), %rax
jmp 0x30af
leaq 0x78(%rsp), %rdi
callq 0x53a4
leaq 0x98(%rsp), %rdi
callq 0x5346
addq $0x4b8, %rsp            # imm = 0x4B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x9c42(%rip), %rdi      # 0xd319
leaq 0x9aa6(%rip), %rsi      # 0xd184
leaq 0x9aa8(%rip), %rcx      # 0xd18d
movl $0x2e1, %edx            # imm = 0x2E1
callq 0x21c0
leaq 0x9bd6(%rip), %rdi      # 0xd2cc
leaq 0x9a87(%rip), %rsi      # 0xd184
leaq 0x9a89(%rip), %rcx      # 0xd18d
movl $0x2a6, %edx            # imm = 0x2A6
callq 0x21c0
leaq 0x9bf2(%rip), %rdi      # 0xd307
leaq 0x9a68(%rip), %rsi      # 0xd184
leaq 0x9a6a(%rip), %rcx      # 0xd18d
movl $0x2c1, %edx            # imm = 0x2C1
callq 0x21c0
leaq 0x9bb6(%rip), %rdi      # 0xd2ea
leaq 0x9a49(%rip), %rsi      # 0xd184
leaq 0x9a4b(%rip), %rcx      # 0xd18d
movl $0x2b8, %edx            # imm = 0x2B8
callq 0x21c0
leaq 0x9a1d(%rip), %rdi      # 0xd170
leaq 0x9a2a(%rip), %rsi      # 0xd184
leaq 0x9a2c(%rip), %rcx      # 0xd18d
movl $0x209, %edx            # imm = 0x209
callq 0x21c0
leaq 0x9ae2(%rip), %rdi      # 0xd254
leaq 0x9a0b(%rip), %rsi      # 0xd184
leaq 0x9a0d(%rip), %rcx      # 0xd18d
movl $0x23c, %edx            # imm = 0x23C
callq 0x21c0
leaq 0x9aec(%rip), %rdi      # 0xd27d
leaq 0x99ec(%rip), %rsi      # 0xd184
leaq 0x99ee(%rip), %rcx      # 0xd18d
movl $0x27e, %edx            # imm = 0x27E
callq 0x21c0
leaq 0x9b06(%rip), %rdi      # 0xd2b6
leaq 0x99cd(%rip), %rsi      # 0xd184
leaq 0x99cf(%rip), %rcx      # 0xd18d
movl $0x285, %edx            # imm = 0x285
callq 0x21c0
movq %rax, %r14
jmp 0x3824
jmp 0x37d9
jmp 0x37f8
jmp 0x37d9
jmp 0x37d9
jmp 0x37d9
jmp 0x380f
movq %rax, %r14
leaq 0x10(%rsp), %rdi
callq 0x2130
jmp 0x381a
jmp 0x37f8
jmp 0x380f
jmp 0x37f8
jmp 0x37f8
jmp 0x37f8
jmp 0x37f8
jmp 0x37f8
jmp 0x37f8
movq %rax, %r14
jmp 0x381a
jmp 0x3801
jmp 0x3801
movq %rax, %r14
leaq 0x20(%rsp), %r13
jmp 0x3812
jmp 0x380f
jmp 0x380f
movq %rax, %r14
movq %r13, %rdi
callq 0x690c
leaq 0x78(%rsp), %rdi
callq 0x53a4
leaq 0x98(%rsp), %rdi
callq 0x5346
movq %r14, %rdi
callq 0x23c0