// File: CMU-SAFARI[P]MQSim/src/host/IO_Flow_Trace_Based.cpp
// Function: Host_Components::IO_Flow_Trace_Based::Get_statistics(Utils::Workload_Statistics&, unsigned long (*)(unsigned long), unsigned long (*)(unsigned long))
void IO_Flow_Trace_Based::Get_statistics(Utils::Workload_Statistics &stats, LPA_type (*Convert_host_logical_address_to_device_address)(LHA_type lha),
										 page_status_type (*Find_NVM_subunit_access_bitmap)(LHA_type lha))
{
	stats.Type = Utils::Workload_Type::TRACE_BASED;
	stats.Stream_id = io_queue_id - 1; //In MQSim, there is a simple relation between stream id and the io_queue_id of NVMe
	stats.Min_LHA = start_lsa_on_device;
	stats.Max_LHA = end_lsa_on_device;
	for (int i = 0; i < MAX_ARRIVAL_TIME_HISTOGRAM + 1; i++)
	{
		stats.Write_arrival_time.push_back(0);
		stats.Read_arrival_time.push_back(0);
	}
	for (int i = 0; i < MAX_REQSIZE_HISTOGRAM_ITEMS + 1; i++)
	{
		stats.Write_size_histogram.push_back(0);
		stats.Read_size_histogram.push_back(0);
	}
	stats.Total_generated_requests = 0;
	stats.Total_accessed_lbas = 0;

	std::ifstream trace_file_temp;
	trace_file_temp.open(trace_file_path, std::ios::in);
	if (!trace_file_temp.is_open())
	{
		PRINT_ERROR("Error while opening the input trace file!")
	}

	std::string trace_line;
	char *pEnd;
	sim_time_type last_request_arrival_time = 0;
	sim_time_type sum_inter_arrival = 0;
	uint64_t sum_request_size = 0;
	std::vector<std::string> line_splitted;
	while (std::getline(trace_file_temp, trace_line))
	{
		Utils::Helper_Functions::Remove_cr(trace_line);
		line_splitted.clear();
		Utils::Helper_Functions::Tokenize(trace_line, ASCIILineDelimiter, line_splitted);
		if (line_splitted.size() != ASCIIItemsPerLine)
		{
			break;
		}
		sim_time_type prev_time = last_request_arrival_time;
		last_request_arrival_time = std::strtoull(line_splitted[ASCIITraceTimeColumn].c_str(), &pEnd, 10);
		if (last_request_arrival_time < prev_time)
		{
			PRINT_ERROR("Unexpected request arrival time: " << last_request_arrival_time << "\nMQSim expects request arrival times to be monotonic increasing in the input trace!")
		}
		sim_time_type diff = (last_request_arrival_time - prev_time) / 1000; //The arrival rate histogram is stored in the microsecond unit
		sum_inter_arrival += last_request_arrival_time - prev_time;

		unsigned int LBA_count = std::strtoul(line_splitted[ASCIITraceSizeColumn].c_str(), &pEnd, 0);
		sum_request_size += LBA_count;
		LHA_type start_LBA = std::strtoull(line_splitted[ASCIITraceAddressColumn].c_str(), &pEnd, 0);
		if (start_LBA <= (end_lsa_on_device - start_lsa_on_device))
		{
			start_LBA += start_lsa_on_device;
		}
		else
		{
			start_LBA = start_lsa_on_device + start_LBA % (end_lsa_on_device - start_lsa_on_device);
		}
		LHA_type end_LBA = start_LBA + LBA_count - 1;
		if (end_LBA > end_lsa_on_device)
		{
			end_LBA = start_lsa_on_device + (end_LBA - end_lsa_on_device) - 1;
		}

		//Address access pattern statistics
		while (start_LBA <= end_LBA)
		{
			LPA_type device_address = Convert_host_logical_address_to_device_address(start_LBA);
			page_status_type access_status_bitmap = Find_NVM_subunit_access_bitmap(start_LBA);
			if (line_splitted[ASCIITraceTypeColumn].compare(ASCIITraceWriteCode) == 0)
			{
				if (stats.Write_address_access_pattern.find(device_address) == stats.Write_address_access_pattern.end())
				{
					Utils::Address_Histogram_Unit hist;
					hist.Access_count = 1;
					hist.Accessed_sub_units = access_status_bitmap;
					stats.Write_address_access_pattern[device_address] = hist;
				}
				else
				{
					stats.Write_address_access_pattern[device_address].Access_count = stats.Write_address_access_pattern[device_address].Access_count + 1;
					stats.Write_address_access_pattern[device_address].Accessed_sub_units = stats.Write_address_access_pattern[device_address].Accessed_sub_units | access_status_bitmap;
				}

				if (stats.Read_address_access_pattern.find(device_address) != stats.Read_address_access_pattern.end())
				{
					stats.Write_read_shared_addresses.insert(device_address);
				}
			}
			else
			{
				if (stats.Read_address_access_pattern.find(device_address) == stats.Read_address_access_pattern.end())
				{
					Utils::Address_Histogram_Unit hist;
					hist.Access_count = 1;
					hist.Accessed_sub_units = access_status_bitmap;
					stats.Read_address_access_pattern[device_address] = hist;
				}
				else
				{
					stats.Read_address_access_pattern[device_address].Access_count = stats.Read_address_access_pattern[device_address].Access_count + 1;
					stats.Read_address_access_pattern[device_address].Accessed_sub_units = stats.Read_address_access_pattern[device_address].Accessed_sub_units | access_status_bitmap;
				}

				if (stats.Write_address_access_pattern.find(device_address) != stats.Write_address_access_pattern.end())
				{
					stats.Write_read_shared_addresses.insert(device_address);
				}
			}
			stats.Total_accessed_lbas++;
			start_LBA++;
			if (start_LBA > end_lsa_on_device)
			{
				start_LBA = start_lsa_on_device;
			}
		}

		//Request size statistics
		if (line_splitted[ASCIITraceTypeColumn].compare(ASCIITraceWriteCode) == 0)
		{
			if (diff < MAX_ARRIVAL_TIME_HISTOGRAM)
			{
				stats.Write_arrival_time[diff]++;
			}
			else
			{
				stats.Write_arrival_time[MAX_ARRIVAL_TIME_HISTOGRAM]++;
			}

			if (LBA_count < MAX_REQSIZE_HISTOGRAM_ITEMS)
			{
				stats.Write_size_histogram[LBA_count]++;
			}
			else
			{
				stats.Write_size_histogram[MAX_REQSIZE_HISTOGRAM_ITEMS]++;
			}
		}
		else
		{
			if (diff < MAX_ARRIVAL_TIME_HISTOGRAM)
			{
				stats.Read_arrival_time[diff]++;
			}
			else
			{
				stats.Read_arrival_time[MAX_ARRIVAL_TIME_HISTOGRAM]++;
			}

			if (LBA_count < MAX_REQSIZE_HISTOGRAM_ITEMS)
			{
				stats.Read_size_histogram[LBA_count]++;
			}
			else
			{
				stats.Read_size_histogram[(unsigned int)MAX_REQSIZE_HISTOGRAM_ITEMS]++;
			}
		}
		stats.Total_generated_requests++;
	}
	trace_file_temp.close();
	stats.Average_request_size_sector = (unsigned int)(sum_request_size / stats.Total_generated_requests);
	stats.Average_inter_arrival_time_nano_sec = sum_inter_arrival / stats.Total_generated_requests;

	stats.Initial_occupancy_ratio = initial_occupancy_ratio;
	stats.Replay_no = total_replay_no;
}

// Assembly:
subq $0x488, %rsp            # imm = 0x488
movq %rdi, 0x480(%rsp)
movq %rsi, 0x478(%rsp)
movq %rdx, 0x470(%rsp)
movq %rcx, 0x468(%rsp)
movq 0x480(%rsp), %rax
movq %rax, 0x110(%rsp)
movq 0x478(%rsp), %rcx
movl $0x1, (%rcx)
movzwl 0xb0(%rax), %ecx
subl $0x1, %ecx
movw %cx, %dx
movq 0x478(%rsp), %rcx
movw %dx, 0x4(%rcx)
movq 0x68(%rax), %rdx
movq 0x478(%rsp), %rcx
movq %rdx, 0x130(%rcx)
movq 0x70(%rax), %rcx
movq 0x478(%rsp), %rax
movq %rcx, 0x138(%rax)
movl $0x0, 0x464(%rsp)
cmpl $0xf4241, 0x464(%rsp) # imm = 0xF4241
jge 0x3a1e9
movq 0x478(%rsp), %rdi
addq $0x28, %rdi
movq $0x0, 0x458(%rsp)
leaq 0x458(%rsp), %rsi
callq 0x3b170
movq 0x478(%rsp), %rdi
addq $0x40, %rdi
movq $0x0, 0x450(%rsp)
leaq 0x450(%rsp), %rsi
callq 0x3b170
movl 0x464(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x464(%rsp)
jmp 0x3a17f
movl $0x0, 0x44c(%rsp)
cmpl $0x401, 0x44c(%rsp) # imm = 0x401
jge 0x3a262
movq 0x478(%rsp), %rdi
addq $0x180, %rdi            # imm = 0x180
movl $0x0, 0x448(%rsp)
leaq 0x448(%rsp), %rsi
callq 0x3b1a0
movq 0x478(%rsp), %rdi
addq $0x198, %rdi            # imm = 0x198
movl $0x0, 0x444(%rsp)
leaq 0x444(%rsp), %rsi
callq 0x3b1a0
movl 0x44c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x44c(%rsp)
jmp 0x3a1f4
movq 0x478(%rsp), %rax
movl $0x0, 0x14(%rax)
movq 0x478(%rsp), %rax
movl $0x0, 0x68(%rax)
leaq 0x238(%rsp), %rdi
movq %rdi, 0x108(%rsp)
callq 0x84d0
movq 0x110(%rsp), %rsi
movq 0x108(%rsp), %rdi
addq $0x478, %rsi            # imm = 0x478
movl $0x8, %edx
callq 0x83b0
jmp 0x3a2b8
leaq 0x238(%rsp), %rdi
callq 0x86a0
movb %al, 0x107(%rsp)
jmp 0x3a2ce
movb 0x107(%rsp), %al
testb $0x1, %al
jne 0x3a354
jmp 0x3a2db
movq 0x9fd0e(%rip), %rdi     # 0xd9ff0
leaq 0x705ff(%rip), %rsi     # 0xaa8e8
callq 0x8440
jmp 0x3a2f0
movq 0x9fcf9(%rip), %rdi     # 0xd9ff0
leaq 0x71c9e(%rip), %rsi     # 0xabf9c
callq 0x8440
movq %rax, 0xf8(%rsp)
jmp 0x3a30d
movq 0xf8(%rsp), %rdi
movq 0x9fc3c(%rip), %rsi     # 0xd9f58
callq 0x8480
jmp 0x3a323
movq 0x9fca6(%rip), %rdi     # 0xd9fd0
callq 0x84f0
jmp 0x3a331
movl $0x1, %edi
callq 0x8500
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x230(%rsp)
movl %eax, 0x22c(%rsp)
jmp 0x3aecc
leaq 0x208(%rsp), %rdi
callq 0x85e0
movq $0x0, 0x1f8(%rsp)
movq $0x0, 0x1f0(%rsp)
movq $0x0, 0x1e8(%rsp)
leaq 0x1d0(%rsp), %rdi
callq 0xd320
leaq 0x238(%rsp), %rdi
leaq 0x208(%rsp), %rsi
callq 0x80b0
movq %rax, 0xf0(%rsp)
jmp 0x3a3b1
movq 0xf0(%rsp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x8530
movb %al, 0xef(%rsp)
jmp 0x3a3d1
movb 0xef(%rsp), %al
testb $0x1, %al
jne 0x3a3e1
jmp 0x3ae11
leaq 0x208(%rsp), %rdi
callq 0x3af30
jmp 0x3a3f0
leaq 0x1d0(%rsp), %rdi
movq %rdi, 0xe0(%rsp)
callq 0x3afa0
movq 0xe0(%rsp), %rdx
leaq 0x208(%rsp), %rdi
movl $0x20, %esi
callq 0x3afc0
jmp 0x3a421
leaq 0x1d0(%rsp), %rdi
callq 0x3aef0
cmpq $0x5, %rax
je 0x3a46c
jmp 0x3ae11
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x230(%rsp)
movl %eax, 0x22c(%rsp)
leaq 0x1d0(%rsp), %rdi
callq 0xd3c0
leaq 0x208(%rsp), %rdi
callq 0x8848
jmp 0x3aecc
movq 0x1f8(%rsp), %rax
movq %rax, 0x1c8(%rsp)
leaq 0x1d0(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x3af10
movq %rax, %rdi
callq 0x8190
movq %rax, %rdi
leaq 0x200(%rsp), %rsi
movl $0xa, %edx
callq 0x8850
movq %rax, 0x1f8(%rsp)
movq 0x1f8(%rsp), %rax
cmpq 0x1c8(%rsp), %rax
jae 0x3a565
movq 0x9fb21(%rip), %rdi     # 0xd9ff0
leaq 0x70412(%rip), %rsi     # 0xaa8e8
callq 0x8440
jmp 0x3a4dd
movq 0x9fb0c(%rip), %rdi     # 0xd9ff0
leaq 0x719fd(%rip), %rsi     # 0xabee8
callq 0x8440
movq %rax, 0xd8(%rsp)
jmp 0x3a4fa
movq 0xd8(%rsp), %rdi
movq 0x1f8(%rsp), %rsi
callq 0x8100
movq %rax, 0xd0(%rsp)
jmp 0x3a519
movq 0xd0(%rsp), %rdi
leaq 0x71a9e(%rip), %rsi     # 0xabfc6
callq 0x8440
movq %rax, 0xc8(%rsp)
jmp 0x3a537
movq 0xc8(%rsp), %rdi
movq 0x9fa12(%rip), %rsi     # 0xd9f58
callq 0x8480
jmp 0x3a54d
movq 0x9fa7c(%rip), %rdi     # 0xd9fd0
callq 0x84f0
jmp 0x3a55b
movl $0x1, %edi
callq 0x8500
movq 0x1f8(%rsp), %rax
subq 0x1c8(%rsp), %rax
movl $0x3e8, %ecx            # imm = 0x3E8
xorl %edx, %edx
divq %rcx
movq %rax, 0x1c0(%rsp)
movq 0x1f8(%rsp), %rax
subq 0x1c8(%rsp), %rax
addq 0x1f0(%rsp), %rax
movq %rax, 0x1f0(%rsp)
leaq 0x1d0(%rsp), %rdi
movl $0x3, %esi
callq 0x3af10
movq %rax, %rdi
callq 0x8190
movq %rax, %rdi
leaq 0x200(%rsp), %rsi
xorl %edx, %edx
callq 0x8838
movl %eax, 0x1bc(%rsp)
movl 0x1bc(%rsp), %eax
addq 0x1e8(%rsp), %rax
movq %rax, 0x1e8(%rsp)
leaq 0x1d0(%rsp), %rdi
movl $0x2, %esi
callq 0x3af10
movq %rax, %rdi
callq 0x8190
movq %rax, %rdi
leaq 0x200(%rsp), %rsi
xorl %edx, %edx
callq 0x8850
movq 0x110(%rsp), %rdx
movq %rax, 0x1b0(%rsp)
movq 0x1b0(%rsp), %rax
movq 0x70(%rdx), %rcx
subq 0x68(%rdx), %rcx
cmpq %rcx, %rax
ja 0x3a660
movq 0x110(%rsp), %rax
movq 0x68(%rax), %rax
addq 0x1b0(%rsp), %rax
movq %rax, 0x1b0(%rsp)
jmp 0x3a69c
movq 0x110(%rsp), %rdx
movq 0x68(%rdx), %rax
movq %rax, 0xc0(%rsp)
movq 0x1b0(%rsp), %rax
movq 0x70(%rdx), %rcx
subq 0x68(%rdx), %rcx
xorl %edx, %edx
divq %rcx
movq 0xc0(%rsp), %rax
addq %rdx, %rax
movq %rax, 0x1b0(%rsp)
movq 0x110(%rsp), %rcx
movq 0x1b0(%rsp), %rax
movl 0x1bc(%rsp), %edx
addq %rdx, %rax
subq $0x1, %rax
movq %rax, 0x1a8(%rsp)
movq 0x1a8(%rsp), %rax
cmpq 0x70(%rcx), %rax
jbe 0x3a6f7
movq 0x110(%rsp), %rdx
movq 0x68(%rdx), %rax
movq 0x1a8(%rsp), %rcx
subq 0x70(%rdx), %rcx
addq %rcx, %rax
subq $0x1, %rax
movq %rax, 0x1a8(%rsp)
jmp 0x3a6f9
movq 0x1b0(%rsp), %rax
cmpq 0x1a8(%rsp), %rax
ja 0x3ac7e
movq 0x470(%rsp), %rax
movq 0x1b0(%rsp), %rdi
callq *%rax
movq %rax, 0xb8(%rsp)
jmp 0x3a72b
movq 0xb8(%rsp), %rax
movq %rax, 0x1a0(%rsp)
movq 0x468(%rsp), %rax
movq 0x1b0(%rsp), %rdi
callq *%rax
movq %rax, 0xb0(%rsp)
jmp 0x3a757
movq 0xb0(%rsp), %rax
movq %rax, 0x198(%rsp)
leaq 0x1d0(%rsp), %rdi
movl $0x4, %esi
callq 0x3af10
movq %rax, %rdi
leaq 0x72066(%rip), %rsi     # 0xac7e9
callq 0x8140
cmpl $0x0, %eax
jne 0x3a9f1
movq 0x478(%rsp), %rdi
addq $0x90, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b1f0
movq %rax, 0xa8(%rsp)
jmp 0x3a7b7
movq 0xa8(%rsp), %rax
movq %rax, 0x190(%rsp)
movq 0x478(%rsp), %rdi
addq $0x90, %rdi
callq 0x3b220
movq %rax, 0x188(%rsp)
leaq 0x190(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x3b1d0
testb $0x1, %al
jne 0x3a7fe
jmp 0x3a863
movl $0x1, 0x178(%rsp)
movq 0x198(%rsp), %rax
movq %rax, 0x180(%rsp)
movq 0x478(%rsp), %rdi
addq $0x90, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b250
movq %rax, 0xa0(%rsp)
jmp 0x3a83f
movq 0xa0(%rsp), %rax
movq 0x178(%rsp), %rcx
movq %rcx, (%rax)
movq 0x180(%rsp), %rcx
movq %rcx, 0x8(%rax)
jmp 0x3a946
movq 0x478(%rsp), %rdi
addq $0x90, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b250
movq %rax, 0x98(%rsp)
jmp 0x3a889
movq 0x98(%rsp), %rax
movl (%rax), %eax
incl %eax
movl %eax, 0x8c(%rsp)
movq 0x478(%rsp), %rdi
addq $0x90, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b250
movq %rax, 0x90(%rsp)
jmp 0x3a8c2
movq 0x90(%rsp), %rax
movl 0x8c(%rsp), %ecx
movl %ecx, (%rax)
movq 0x478(%rsp), %rdi
addq $0x90, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b250
movq %rax, 0x80(%rsp)
jmp 0x3a8f9
movq 0x80(%rsp), %rax
movq 0x8(%rax), %rax
movq 0x198(%rsp), %rcx
orq %rcx, %rax
movq %rax, 0x70(%rsp)
movq 0x478(%rsp), %rdi
addq $0x90, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b250
movq %rax, 0x78(%rsp)
jmp 0x3a938
movq 0x78(%rsp), %rax
movq 0x70(%rsp), %rcx
movq %rcx, 0x8(%rax)
movq 0x478(%rsp), %rdi
addq $0xc0, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b1f0
movq %rax, 0x68(%rsp)
jmp 0x3a969
movq 0x68(%rsp), %rax
movq %rax, 0x170(%rsp)
movq 0x478(%rsp), %rdi
addq $0xc0, %rdi
callq 0x3b220
movq %rax, 0x168(%rsp)
leaq 0x170(%rsp), %rdi
leaq 0x168(%rsp), %rsi
callq 0x3b340
testb $0x1, %al
jne 0x3a9ad
jmp 0x3a9ec
movq 0x478(%rsp), %rdi
addq $0xf0, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b360
movb %dl, 0x5f(%rsp)
movq %rax, 0x60(%rsp)
jmp 0x3a9d4
movb 0x5f(%rsp), %al
movq 0x60(%rsp), %rcx
movq %rcx, 0x158(%rsp)
movb %al, 0x160(%rsp)
jmp 0x3ac2a
movq 0x478(%rsp), %rdi
addq $0xc0, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b1f0
movq %rax, 0x50(%rsp)
jmp 0x3aa14
movq 0x50(%rsp), %rax
movq %rax, 0x150(%rsp)
movq 0x478(%rsp), %rdi
addq $0xc0, %rdi
callq 0x3b220
movq %rax, 0x148(%rsp)
leaq 0x150(%rsp), %rdi
leaq 0x148(%rsp), %rsi
callq 0x3b1d0
testb $0x1, %al
jne 0x3aa58
jmp 0x3aab7
movl $0x1, 0x138(%rsp)
movq 0x198(%rsp), %rax
movq %rax, 0x140(%rsp)
movq 0x478(%rsp), %rdi
addq $0xc0, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b250
movq %rax, 0x48(%rsp)
jmp 0x3aa96
movq 0x48(%rsp), %rax
movq 0x138(%rsp), %rcx
movq %rcx, (%rax)
movq 0x140(%rsp), %rcx
movq %rcx, 0x8(%rax)
jmp 0x3ab82
movq 0x478(%rsp), %rdi
addq $0xc0, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b250
movq %rax, 0x40(%rsp)
jmp 0x3aada
movq 0x40(%rsp), %rax
movl (%rax), %eax
incl %eax
movl %eax, 0x34(%rsp)
movq 0x478(%rsp), %rdi
addq $0xc0, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b250
movq %rax, 0x38(%rsp)
jmp 0x3ab0a
movq 0x38(%rsp), %rax
movl 0x34(%rsp), %ecx
movl %ecx, (%rax)
movq 0x478(%rsp), %rdi
addq $0xc0, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b250
movq %rax, 0x28(%rsp)
jmp 0x3ab38
movq 0x28(%rsp), %rax
movq 0x8(%rax), %rax
movq 0x198(%rsp), %rcx
orq %rcx, %rax
movq %rax, 0x18(%rsp)
movq 0x478(%rsp), %rdi
addq $0xc0, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b250
movq %rax, 0x20(%rsp)
jmp 0x3ab74
movq 0x20(%rsp), %rax
movq 0x18(%rsp), %rcx
movq %rcx, 0x8(%rax)
movq 0x478(%rsp), %rdi
addq $0x90, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b1f0
movq %rax, 0x10(%rsp)
jmp 0x3aba5
movq 0x10(%rsp), %rax
movq %rax, 0x130(%rsp)
movq 0x478(%rsp), %rdi
addq $0x90, %rdi
callq 0x3b220
movq %rax, 0x128(%rsp)
leaq 0x130(%rsp), %rdi
leaq 0x128(%rsp), %rsi
callq 0x3b340
testb $0x1, %al
jne 0x3abe9
jmp 0x3ac28
movq 0x478(%rsp), %rdi
addq $0xf0, %rdi
leaq 0x1a0(%rsp), %rsi
callq 0x3b360
movb %dl, 0x7(%rsp)
movq %rax, 0x8(%rsp)
jmp 0x3ac10
movb 0x7(%rsp), %al
movq 0x8(%rsp), %rcx
movq %rcx, 0x118(%rsp)
movb %al, 0x120(%rsp)
jmp 0x3ac2a
movq 0x110(%rsp), %rcx
movq 0x478(%rsp), %rax
movl 0x68(%rax), %edx
addl $0x1, %edx
movl %edx, 0x68(%rax)
movq 0x1b0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x1b0(%rsp)
movq 0x1b0(%rsp), %rax
cmpq 0x70(%rcx), %rax
jbe 0x3ac79
movq 0x110(%rsp), %rax
movq 0x68(%rax), %rax
movq %rax, 0x1b0(%rsp)
jmp 0x3a6f9
leaq 0x1d0(%rsp), %rdi
movl $0x4, %esi
callq 0x3af10
movq %rax, %rdi
leaq 0x71b4f(%rip), %rsi     # 0xac7e9
callq 0x8140
cmpl $0x0, %eax
jne 0x3ad53
cmpq $0xf4240, 0x1c0(%rsp) # imm = 0xF4240
jae 0x3acdb
movq 0x478(%rsp), %rdi
addq $0x28, %rdi
movq 0x1c0(%rsp), %rsi
callq 0x3b3c0
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
jmp 0x3acfb
movq 0x478(%rsp), %rdi
addq $0x28, %rdi
movl $0xf4240, %esi          # imm = 0xF4240
callq 0x3b3c0
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
cmpl $0x400, 0x1bc(%rsp) # imm = 0x400
jae 0x3ad2e
movq 0x478(%rsp), %rdi
addq $0x180, %rdi            # imm = 0x180
movl 0x1bc(%rsp), %eax
movl %eax, %esi
callq 0x3b3e0
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x3ad4e
movq 0x478(%rsp), %rdi
addq $0x180, %rdi            # imm = 0x180
movl $0x400, %esi            # imm = 0x400
callq 0x3b3e0
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x3adfb
cmpq $0xf4240, 0x1c0(%rsp) # imm = 0xF4240
jae 0x3ad86
movq 0x478(%rsp), %rdi
addq $0x40, %rdi
movq 0x1c0(%rsp), %rsi
callq 0x3b3c0
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
jmp 0x3ada6
movq 0x478(%rsp), %rdi
addq $0x40, %rdi
movl $0xf4240, %esi          # imm = 0xF4240
callq 0x3b3c0
movq (%rax), %rcx
addq $0x1, %rcx
movq %rcx, (%rax)
cmpl $0x400, 0x1bc(%rsp) # imm = 0x400
jae 0x3add9
movq 0x478(%rsp), %rdi
addq $0x198, %rdi            # imm = 0x198
movl 0x1bc(%rsp), %eax
movl %eax, %esi
callq 0x3b3e0
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x3adf9
movq 0x478(%rsp), %rdi
addq $0x198, %rdi            # imm = 0x198
movl $0x400, %esi            # imm = 0x400
callq 0x3b3e0
movl (%rax), %ecx
addl $0x1, %ecx
movl %ecx, (%rax)
jmp 0x3adfb
movq 0x478(%rsp), %rax
movl 0x14(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x14(%rax)
jmp 0x3a392
leaq 0x238(%rsp), %rdi
callq 0x80d0
jmp 0x3ae20
movq 0x1e8(%rsp), %rax
movq 0x478(%rsp), %rcx
movl 0x14(%rcx), %ecx
xorl %edx, %edx
divq %rcx
movl %eax, %ecx
movq 0x478(%rsp), %rax
movl %ecx, 0x178(%rax)
movq 0x1f0(%rsp), %rax
movq 0x478(%rsp), %rcx
movl 0x14(%rcx), %ecx
xorl %edx, %edx
divq %rcx
movq %rax, %rdx
movq 0x110(%rsp), %rax
movq 0x478(%rsp), %rcx
movq %rdx, 0x168(%rcx)
movsd 0x40(%rax), %xmm0
movq 0x478(%rsp), %rcx
movsd %xmm0, 0x8(%rcx)
movl 0x6a0(%rax), %ecx
movq 0x478(%rsp), %rax
movl %ecx, 0x10(%rax)
leaq 0x1d0(%rsp), %rdi
callq 0xd3c0
leaq 0x208(%rsp), %rdi
callq 0x8848
leaq 0x238(%rsp), %rdi
callq 0x8120
addq $0x488, %rsp            # imm = 0x488
retq
leaq 0x238(%rsp), %rdi
callq 0x8120
movq 0x230(%rsp), %rdi
callq 0x8770
nopw %cs:(%rax,%rax)