// File: /workspace/github_cpp_makefile_star2_O3/CMU-SAFARI[P]MQSim/src/exec/Host_System.cpp
// Function: Host_System::Host_System(Host_Parameter_Set*, bool, SSD_Components::Host_Interface_Base*)
Host_System::Host_System(Host_Parameter_Set* parameters, bool preconditioning_required, SSD_Components::Host_Interface_Base* ssd_host_interface):
	MQSimEngine::Sim_Object("Host"), preconditioning_required(preconditioning_required)
{
	Simulator->AddObject(this);

	//Create the main components of the host system
	if (((SSD_Components::Host_Interface_NVMe*)ssd_host_interface)->GetType() == HostInterface_Types::SATA) {
		this->SATA_hba = new Host_Components::SATA_HBA(ID() + ".SATA_HBA", ((SSD_Components::Host_Interface_SATA*)ssd_host_interface)->Get_ncq_depth(), parameters->SATA_Processing_Delay, NULL, NULL);
	} else {
		this->SATA_hba = NULL;
	}
	this->Link = new Host_Components::PCIe_Link(this->ID() + ".PCIeLink", NULL, NULL, parameters->PCIe_Lane_Bandwidth, parameters->PCIe_Lane_Count);
	this->PCIe_root_complex = new Host_Components::PCIe_Root_Complex(this->Link, ssd_host_interface->GetType(), this->SATA_hba, NULL);
	this->Link->Set_root_complex(this->PCIe_root_complex);
	this->PCIe_switch = new Host_Components::PCIe_Switch(this->Link, ssd_host_interface);
	this->Link->Set_pcie_switch(this->PCIe_switch);
	Simulator->AddObject(this->Link);

	//Create IO flows
	LHA_type address_range_per_flow = ssd_host_interface->Get_max_logical_sector_address() / parameters->IO_Flow_Definitions.size();
	for (uint16_t flow_id = 0; flow_id < parameters->IO_Flow_Definitions.size(); flow_id++) {
		Host_Components::IO_Flow_Base* io_flow = NULL;
		//No flow should ask for I/O queue id 0, it is reserved for NVMe Admin command queue pair
		//Hence, we use flow_id + 1 (which is equal to 1, 2, ...) as the requested I/O queue id
		uint16_t nvme_sq_size = 0, nvme_cq_size = 0;
		switch (((SSD_Components::Host_Interface_NVMe*)ssd_host_interface)->GetType()) {
			case HostInterface_Types::NVME:
				nvme_sq_size = ((SSD_Components::Host_Interface_NVMe*)ssd_host_interface)->Get_submission_queue_depth();
				nvme_cq_size = ((SSD_Components::Host_Interface_NVMe*)ssd_host_interface)->Get_completion_queue_depth();
				break;
			default:
				break;
		}

		switch (parameters->IO_Flow_Definitions[flow_id]->Type) {
			case Flow_Type::SYNTHETIC: {
				IO_Flow_Parameter_Set_Synthetic* flow_param = (IO_Flow_Parameter_Set_Synthetic*)parameters->IO_Flow_Definitions[flow_id];
				if (flow_param->Working_Set_Percentage > 100 || flow_param->Working_Set_Percentage < 1) {
					flow_param->Working_Set_Percentage = 100;
				}
				io_flow = new Host_Components::IO_Flow_Synthetic(this->ID() + ".IO_Flow.Synth.No_" + std::to_string(flow_id), flow_id,
					Utils::Logical_Address_Partitioning_Unit::Start_lha_available_to_flow(flow_id),
					Utils::Logical_Address_Partitioning_Unit::End_lha_available_to_flow(flow_id),
					((double)flow_param->Working_Set_Percentage / 100.0), FLOW_ID_TO_Q_ID(flow_id), nvme_sq_size, nvme_cq_size,
					flow_param->Priority_Class, flow_param->Read_Percentage / double(100.0), flow_param->Address_Distribution, flow_param->Percentage_of_Hot_Region / double(100.0),
					flow_param->Request_Size_Distribution, flow_param->Average_Request_Size, flow_param->Variance_Request_Size,
					flow_param->Synthetic_Generator_Type, (flow_param->Bandwidth == 0? 0 :NanoSecondCoeff / ((flow_param->Bandwidth / SECTOR_SIZE_IN_BYTE) / flow_param->Average_Request_Size)),
					flow_param->Average_No_of_Reqs_in_Queue, flow_param->Generated_Aligned_Addresses, flow_param->Address_Alignment_Unit,
					flow_param->Seed, flow_param->Stop_Time, flow_param->Initial_Occupancy_Percentage / double(100.0), flow_param->Total_Requests_To_Generate, ssd_host_interface->GetType(), this->PCIe_root_complex, this->SATA_hba,
					parameters->Enable_ResponseTime_Logging, parameters->ResponseTime_Logging_Period_Length, parameters->Input_file_path + ".IO_Flow.No_" + std::to_string(flow_id) + ".log");
				this->IO_flows.push_back(io_flow);
				break;
			}
			case Flow_Type::TRACE: {
				IO_Flow_Parameter_Set_Trace_Based * flow_param = (IO_Flow_Parameter_Set_Trace_Based*)parameters->IO_Flow_Definitions[flow_id];
				io_flow = new Host_Components::IO_Flow_Trace_Based(this->ID() + ".IO_Flow.Trace." + flow_param->File_Path, flow_id,
					Utils::Logical_Address_Partitioning_Unit::Start_lha_available_to_flow(flow_id), Utils::Logical_Address_Partitioning_Unit::End_lha_available_to_flow(flow_id),
					FLOW_ID_TO_Q_ID(flow_id), nvme_sq_size, nvme_cq_size,
					flow_param->Priority_Class, flow_param->Initial_Occupancy_Percentage / double(100.0),
					flow_param->File_Path, flow_param->Time_Unit, flow_param->Relay_Count, flow_param->Percentage_To_Be_Executed,
					ssd_host_interface->GetType(), this->PCIe_root_complex, this->SATA_hba,
					parameters->Enable_ResponseTime_Logging, parameters->ResponseTime_Logging_Period_Length, parameters->Input_file_path + ".IO_Flow.No_" + std::to_string(flow_id) + ".log");

				this->IO_flows.push_back(io_flow);
				break;
			}
			default:
				throw "The specified IO flow type is not supported.\n";
		}
		Simulator->AddObject(io_flow);
	}
	this->PCIe_root_complex->Set_io_flows(&this->IO_flows);
	if (((SSD_Components::Host_Interface_NVMe*)ssd_host_interface)->GetType() == HostInterface_Types::SATA) {
		this->SATA_hba->Set_io_flows(&this->IO_flows);
		this->SATA_hba->Set_root_complex(this->PCIe_root_complex);
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x238, %rsp            # imm = 0x238
movq %rcx, %r14
movl %edx, %ebp
movq %rdi, %r12
leaq 0x28(%rsp), %r13
movq %r13, -0x10(%r13)
leaq 0x424b3(%rip), %rsi     # 0x56ea8
leaq 0x424b0(%rip), %rdx     # 0x56eac
leaq 0x18(%rsp), %rdi
callq 0xafc8
leaq 0x18(%rsp), %rsi
movq %r12, %rdi
callq 0x164ce
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x14a22
callq 0x7370
leaq 0x58f97(%rip), %rax     # 0x6d9c0
movq %rax, (%r12)
leaq 0x58fc4(%rip), %rax     # 0x6d9f8
movq %rax, 0x30(%r12)
leaq 0x58(%r12), %rax
movq %rax, 0xc8(%rsp)
xorpd %xmm0, %xmm0
movupd %xmm0, 0x58(%r12)
movq $0x0, 0x68(%r12)
movb %bpl, 0x78(%r12)
callq 0x28018
movq %rax, %rdi
movq %r12, %rsi
callq 0x2808c
cmpl $0x0, 0x38(%r14)
movq %r12, 0x10(%rsp)
je 0x14a89
movq $0x0, 0x50(%r12)
jmp 0x14b65
movl $0x1b0, %edi            # imm = 0x1B0
callq 0x73a0
movq %rax, %r15
leaq 0x18(%rsp), %rdi
movq %r13, (%rdi)
movq 0x8(%r12), %rsi
movq 0x10(%r12), %rdx
addq %rsi, %rdx
callq 0xaf32
leaq 0x423f6(%rip), %rsi     # 0x56ead
leaq 0x18(%rsp), %rdi
callq 0x7690
leaq 0x228(%rsp), %rbx
movq %rbx, -0x10(%rbx)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x14af1
movq %rdx, 0x218(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x228(%rsp)
jmp 0x14af9
movupd (%rcx), %xmm0
movupd %xmm0, (%rbx)
movq 0x8(%rax), %rdx
movq %rdx, 0x220(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq %r14, %rdi
callq 0x449f2
leaq 0x5aa45(%rip), %rcx     # 0x6f568
movq (%rcx), %rcx
movzwl %ax, %edx
leaq 0x218(%rsp), %rsi
movq %r15, %rdi
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0x24f98
movq %r15, 0x50(%r12)
movq 0x218(%rsp), %rdi
cmpq %rbx, %rdi
je 0x14b56
callq 0x7370
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x14b65
callq 0x7370
movl $0x100, %edi            # imm = 0x100
callq 0x73a0
movq %rax, %r15
leaq 0x78(%rsp), %rbp
movq %rbp, -0x10(%rbp)
movq 0x8(%r12), %rsi
movq 0x10(%r12), %rdx
addq %rsi, %rdx
leaq 0x68(%rsp), %rdi
callq 0xaf32
leaq 0x4231e(%rip), %rsi     # 0x56eb7
leaq 0x68(%rsp), %rdi
callq 0x7690
movq %r13, 0x18(%rsp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x14bc6
movq %rdx, 0x18(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x28(%rsp)
jmp 0x14bd0
movupd (%rcx), %xmm0
movupd %xmm0, (%r13)
movq 0x8(%rax), %rdx
leaq 0x18(%rsp), %rsi
movq %rdx, 0x8(%rsi)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
leaq 0x5a8a5(%rip), %rax     # 0x6f498
movsd (%rax), %xmm0
leaq 0x5a8a2(%rip), %rax     # 0x6f4a0
movl (%rax), %r8d
subq $0x8, %rsp
movq %r15, %rdi
xorl %edx, %edx
xorl %ecx, %ecx
movl $0x14, %r9d
pushq $0x2
pushq $0x6
pushq $0x80
callq 0x24518
addq $0x20, %rsp
movq %r15, 0x40(%r12)
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x14c38
callq 0x7370
movq 0x68(%rsp), %rdi
cmpq %rbp, %rdi
je 0x14c47
callq 0x7370
movl $0x20, %edi
callq 0x73a0
movq %rax, %r15
movl 0x38(%r14), %edx
movq 0x40(%r12), %rsi
movq 0x50(%r12), %rcx
movq %rax, %rdi
xorl %r8d, %r8d
callq 0x24dc4
movq %r15, 0x38(%r12)
movq 0x40(%r12), %rdi
movq %r15, %rsi
callq 0x24628
movl $0x10, %edi
callq 0x73a0
movq %rax, %r15
movq 0x40(%r12), %rsi
movq %rax, %rdi
movq %r14, %rdx
callq 0x24f44
movq %r15, 0x48(%r12)
movq 0x40(%r12), %rdi
movq %r15, %rsi
callq 0x2462e
callq 0x28018
movq 0x40(%r12), %rsi
movq %rax, %rdi
callq 0x2808c
movq %r14, 0xd8(%rsp)
movq %r14, %rdi
callq 0x4078c
leaq 0x5a8c1(%rip), %rcx     # 0x6f598
movq (%rcx), %rax
cmpq %rax, 0x8(%rcx)
je 0x159c1
leaq 0x158(%rsp), %r15
xorl %r14d, %r14d
xorl %ebx, %ebx
movq $0x0, 0x38(%rsp)
movq 0xd8(%rsp), %rdi
cmpl $0x1, 0x38(%rdi)
jne 0x14d2e
callq 0x41bb0
movl %eax, 0x44(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x41bb8
movl %eax, 0x40(%rsp)
leaq 0x5a86f(%rip), %rax     # 0x6f598
movq (%rax), %rax
jmp 0x14d3e
movl $0x0, 0x44(%rsp)
movl $0x0, 0x40(%rsp)
movq (%rax,%r14,8), %r14
movl 0xc(%r14), %eax
cmpl $0x1, %eax
je 0x14de3
testl %eax, %eax
jne 0x15a14
movl 0x4c(%r14), %eax
addl $-0x65, %eax
cmpl $-0x65, %eax
ja 0x14d6b
movl $0x64, 0x4c(%r14)
movl $0x520, %edi            # imm = 0x520
callq 0x73a0
movq %rax, 0xd0(%rsp)
movq %r15, 0x148(%rsp)
movq 0x8(%r12), %rsi
movq 0x10(%r12), %rdx
addq %rsi, %rdx
leaq 0x148(%rsp), %r15
movq %r15, %rdi
callq 0xaf32
movq %r15, %rdi
leaq 0x42115(%rip), %rsi     # 0x56ec1
callq 0x7690
leaq 0xb8(%rsp), %r15
movq %rbp, 0x68(%rsp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x14ea6
movq %rdx, 0x68(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x78(%rsp)
jmp 0x14eaf
movl $0x6d0, %edi            # imm = 0x6D0
callq 0x73a0
movq %rax, 0x8(%rsp)
movq %r15, 0x148(%rsp)
movq 0x8(%r12), %rsi
movq 0x10(%r12), %rdx
addq %rsi, %rdx
leaq 0x148(%rsp), %r15
movq %r15, %rdi
callq 0xaf32
movq %r15, %rdi
leaq 0x420c5(%rip), %rsi     # 0x56ee6
callq 0x7690
movq %rbp, 0x68(%rsp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x14e49
movq %rdx, 0x68(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x78(%rsp)
jmp 0x14e52
movupd (%rcx), %xmm0
movupd %xmm0, (%rbp)
movq 0x8(%rax), %rdx
movq %rdx, 0x70(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq 0x50(%r14), %rsi
movq 0x58(%r14), %rdx
leaq 0x68(%rsp), %rdi
callq 0x7130
movq %r13, 0x18(%rsp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x14f9b
movq %rdx, 0x18(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x28(%rsp)
jmp 0x14fa5
movupd (%rcx), %xmm0
movupd %xmm0, (%rbp)
movq 0x8(%rax), %rdx
movq %rdx, 0x70(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movzwl %bx, %eax
movl %eax, 0x8(%rsp)
movl $0x1, %ebp
cmpw $0xa, %bx
jb 0x14f03
movl $0x2, %ebp
cmpw $0x64, %bx
jb 0x14f03
movl $0x3, %ebp
cmpl $0x3e8, 0x8(%rsp)       # imm = 0x3E8
jb 0x14f03
cmpl $0x2710, 0x8(%rsp)      # imm = 0x2710
movl $0x5, %ebp
sbbl $0x0, %ebp
movl %ebp, %esi
movq %r15, 0xa8(%rsp)
leaq 0xa8(%rsp), %rdi
movl $0x2d, %edx
callq 0x7420
movq 0xa8(%rsp), %rdi
movl %ebp, %esi
movl 0x8(%rsp), %edx
callq 0xaec5
movq 0x68(%rsp), %rcx
movl $0xf, %edi
leaq 0x78(%rsp), %rax
cmpq %rax, %rcx
je 0x14f4b
movq 0x78(%rsp), %rdi
movq 0x70(%rsp), %r8
movq 0xa8(%rsp), %rsi
movq 0xb0(%rsp), %rdx
leaq (%rdx,%r8), %rax
cmpq %rdi, %rax
leaq 0x88(%rsp), %rbp
jbe 0x14f8c
movl $0xf, %edi
cmpq %r15, %rsi
je 0x14f83
movq 0xb8(%rsp), %rdi
cmpq %rdi, %rax
jbe 0x1519f
leaq 0x68(%rsp), %rdi
callq 0x7130
jmp 0x151b0
movupd (%rcx), %xmm0
movupd %xmm0, (%r13)
movq 0x8(%rax), %rdx
movq %rdx, 0x20(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movzwl %bx, %r15d
movl %r15d, %edi
callq 0x52f66
movq %rax, 0xd0(%rsp)
movl %r15d, %edi
callq 0x52fcc
movq %rax, 0x118(%rsp)
movl 0x10(%r14), %eax
movq %rax, 0x110(%rsp)
movl 0x38(%r14), %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x41e9f(%rip), %xmm0    # 0x56ea0
movsd %xmm0, 0x108(%rsp)
leaq 0x208(%rsp), %rax
movq %rax, 0x1f8(%rsp)
movq 0x50(%r14), %rsi
movq 0x58(%r14), %rdx
addq %rsi, %rdx
leaq 0x1f8(%rsp), %rdi
callq 0xaf32
movl 0x78(%r14), %eax
movq %rax, 0x100(%rsp)
movl 0x70(%r14), %eax
movq %rax, 0xf0(%rsp)
movl 0x74(%r14), %eax
movq %rax, 0xf8(%rsp)
movq 0xd8(%rsp), %rax
movl 0x38(%rax), %eax
movq %rax, 0xe8(%rsp)
movq 0x38(%r12), %rax
movq %rax, 0xe0(%rsp)
movq 0x50(%r12), %r12
leaq 0x5a4ee(%rip), %rax     # 0x6f570
movb (%rax), %r13b
leaq 0x5a41c(%rip), %rax     # 0x6f4a8
movq (%rax), %rbp
leaq 0x58(%rsp), %rax
movq %rax, 0x48(%rsp)
leaq 0x5a4d8(%rip), %rax     # 0x6f578
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq 0x48(%rsp), %r14
movq %r14, %rdi
callq 0xaf32
movq %r14, %rdi
leaq 0x41e13(%rip), %rsi     # 0x56ed4
callq 0x7690
movl $0x1, %r14d
cmpw $0xa, %bx
jb 0x150fe
movl $0x2, %r14d
cmpw $0x64, %bx
jb 0x150fe
movl $0x3, %r14d
cmpl $0x3e8, %r15d           # imm = 0x3E8
jb 0x150fe
cmpl $0x2710, %r15d          # imm = 0x2710
movl $0x5, %r14d
sbbl $0x0, %r14d
movl %r14d, %esi
leaq 0x98(%rsp), %rax
movq %rax, 0x88(%rsp)
leaq 0x88(%rsp), %rdi
movl $0x2d, %edx
callq 0x7420
movq 0x88(%rsp), %rdi
movl %r14d, %esi
movl %r15d, %edx
callq 0xaec5
movq 0x48(%rsp), %rcx
movl $0xf, %edi
leaq 0x58(%rsp), %rax
cmpq %rax, %rcx
je 0x1514f
movq 0x58(%rsp), %rdi
movq 0x50(%rsp), %r8
movq 0x88(%rsp), %rsi
movq 0x90(%rsp), %rdx
leaq (%rdx,%r8), %rax
cmpq %rdi, %rax
jbe 0x15190
movl $0xf, %edi
leaq 0x98(%rsp), %r9
cmpq %r9, %rsi
je 0x15187
movq 0x98(%rsp), %rdi
cmpq %rdi, %rax
jbe 0x15478
leaq 0x48(%rsp), %rdi
callq 0x7130
jmp 0x15489
leaq 0xa8(%rsp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x73e0
movq %r13, 0x18(%rsp)
movq (%rax), %rdx
leaq 0x10(%rax), %rcx
cmpq %rcx, %rdx
je 0x151d0
movq %rdx, 0x18(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x28(%rsp)
jmp 0x151da
movupd (%rcx), %xmm0
movupd %xmm0, (%r13)
movl 0x8(%rsp), %r15d
movq %rax, %rdx
addq $0x8, %rdx
movq 0x8(%rax), %rsi
movq %rsi, 0x20(%rsp)
movq %rcx, (%rax)
movq $0x0, (%rdx)
movb $0x0, (%rcx)
movl %r15d, %edi
callq 0x52f66
movq %rax, %r13
movl %r15d, %edi
callq 0x52fcc
movq %rax, %r10
movl 0x10(%r14), %ecx
movl 0x4c(%r14), %eax
movq %rax, 0x1b8(%rsp)
movsbl 0x54(%r14), %r15d
movl 0x58(%r14), %edx
movsbl 0x5c(%r14), %r11d
movl 0x64(%r14), %esi
movl 0x68(%r14), %edi
movl 0x6c(%r14), %r8d
movl 0x50(%r14), %r9d
movl 0x78(%r14), %eax
testl %eax, %eax
movq %rcx, 0x118(%rsp)
movq %rdx, 0x110(%rsp)
movq %rsi, 0x108(%rsp)
movq %rdi, 0x100(%rsp)
movq %r8, 0xf8(%rsp)
movq %r9, 0xf0(%rsp)
movq %r13, 0xe8(%rsp)
movq %r10, 0x1f0(%rsp)
movl %r11d, 0x124(%rsp)
movl %r15d, 0x120(%rsp)
je 0x152b4
shrl $0x9, %eax
xorl %edx, %edx
divl %edi
movl %eax, %ecx
movl $0x3b9aca00, %eax       # imm = 0x3B9ACA00
xorl %edx, %edx
divl %ecx
movq %rax, 0xe0(%rsp)
jmp 0x152c0
movq $0x0, 0xe0(%rsp)
movl 0x74(%r14), %eax
movq %rax, 0x1e8(%rsp)
movb 0x5d(%r14), %r13b
movl 0x60(%r14), %eax
movq %rax, 0x1e0(%rsp)
movl 0x70(%r14), %eax
movq %rax, 0x1d8(%rsp)
movl 0x38(%r14), %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movq 0x80(%r14), %rax
movq %rax, 0x1d0(%rsp)
divsd 0x41b95(%rip), %xmm0    # 0x56ea0
movsd %xmm0, 0x1a8(%rsp)
movl 0x88(%r14), %eax
movq %rax, 0x1c8(%rsp)
movq 0xd8(%rsp), %rax
movl 0x38(%rax), %eax
movq %rax, 0x1c0(%rsp)
movq 0x38(%r12), %rax
movq %rax, 0x1b0(%rsp)
movq 0x50(%r12), %r14
leaq 0x5a221(%rip), %rax     # 0x6f570
movb (%rax), %r15b
leaq 0x5a14f(%rip), %rax     # 0x6f4a8
movq (%rax), %r12
leaq 0x98(%rsp), %rax
movq %rax, 0x88(%rsp)
leaq 0x5a205(%rip), %rax     # 0x6f578
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
movq %rbp, %rdi
callq 0xaf32
movq %rbp, %rdi
leaq 0x41b45(%rip), %rsi     # 0x56ed4
callq 0x7690
movl $0x1, %ebp
cmpw $0xa, %bx
jb 0x153c9
movl $0x2, %ebp
cmpw $0x64, %bx
jb 0x153c9
movl $0x3, %ebp
cmpl $0x3e8, 0x8(%rsp)       # imm = 0x3E8
jb 0x153c9
cmpl $0x2710, 0x8(%rsp)      # imm = 0x2710
movl $0x5, %ebp
sbbl $0x0, %ebp
movl %ebp, %esi
leaq 0x138(%rsp), %rax
movq %rax, 0x128(%rsp)
leaq 0x128(%rsp), %rdi
movl $0x2d, %edx
callq 0x7420
movq 0x128(%rsp), %rdi
movl %ebp, %esi
movl 0x8(%rsp), %edx
callq 0xaec5
movq 0x88(%rsp), %rcx
movl $0xf, %edi
leaq 0x98(%rsp), %rax
cmpq %rax, %rcx
je 0x15422
movq 0x98(%rsp), %rdi
movq 0x90(%rsp), %r8
movq 0x128(%rsp), %rsi
movq 0x130(%rsp), %rdx
leaq (%rdx,%r8), %rax
cmpq %rdi, %rax
jbe 0x15466
movl $0xf, %edi
leaq 0x138(%rsp), %r9
cmpq %r9, %rsi
je 0x1545d
movq 0x138(%rsp), %rdi
cmpq %rdi, %rax
jbe 0x156cf
leaq 0x88(%rsp), %rdi
callq 0x7130
jmp 0x156e0
leaq 0x88(%rsp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x73e0
leaq 0xb8(%rsp), %rsi
movq %rsi, 0xa8(%rsp)
movq (%rax), %rdx
leaq 0x10(%rax), %rcx
cmpq %rcx, %rdx
je 0x154ba
movq %rdx, 0xa8(%rsp)
movq (%rcx), %rdx
movq %rdx, 0xb8(%rsp)
jmp 0x154c2
movupd (%rcx), %xmm0
movupd %xmm0, (%rsi)
movq %rax, %rdx
addq $0x8, %rdx
movq 0x8(%rax), %rsi
movq %rsi, 0xb0(%rsp)
movq %rcx, (%rax)
movq $0x0, (%rdx)
movb $0x0, (%rcx)
leaq 0xa8(%rsp), %rdi
leaq 0x419f0(%rip), %rsi     # 0x56ee1
callq 0x7690
leaq 0x178(%rsp), %rsi
movq %rsi, 0x168(%rsp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x1552a
movq %rdx, 0x168(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x178(%rsp)
jmp 0x15532
movupd (%rcx), %xmm0
movupd %xmm0, (%rsi)
leal 0x1(%r15), %edx
movq 0x8(%rax), %rsi
movq %rsi, 0x170(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
subq $0x8, %rsp
movzbl %r13b, %r11d
movzwl 0x48(%rsp), %r10d
movzwl 0x4c(%rsp), %eax
movzwl %dx, %r9d
movq 0x10(%rsp), %r13
movq %r13, %rdi
leaq 0x20(%rsp), %rsi
movl %r15d, %edx
movq 0xd8(%rsp), %rcx
movq 0x120(%rsp), %r8
movsd 0x110(%rsp), %xmm0
leaq 0x170(%rsp), %r14
pushq %r14
pushq %rbp
pushq %r11
pushq %r12
pushq 0x108(%rsp)
pushq 0x118(%rsp)
pushq 0x128(%rsp)
pushq 0x138(%rsp)
pushq 0x148(%rsp)
leaq 0x248(%rsp), %r11
pushq %r11
pushq 0x168(%rsp)
pushq %r10
pushq %rax
callq 0x228f0
addq $0x70, %rsp
movq %r13, 0x38(%rsp)
movq 0x168(%rsp), %rdi
leaq 0x178(%rsp), %rax
cmpq %rax, %rdi
movq 0x10(%rsp), %r12
leaq 0x28(%rsp), %r13
leaq 0x78(%rsp), %rbp
leaq 0x158(%rsp), %r15
je 0x15616
callq 0x7370
movq 0xa8(%rsp), %rdi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rdi
je 0x15630
callq 0x7370
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x1564a
callq 0x7370
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x1565e
callq 0x7370
movq 0x1f8(%rsp), %rdi
leaq 0x208(%rsp), %rax
cmpq %rax, %rdi
je 0x15678
callq 0x7370
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x15687
callq 0x7370
movq 0x68(%rsp), %rdi
cmpq %rbp, %rdi
je 0x15696
callq 0x7370
movq 0x148(%rsp), %rdi
cmpq %r15, %rdi
je 0x156a8
callq 0x7370
movq 0x60(%r12), %rsi
cmpq 0x68(%r12), %rsi
jne 0x15969
movq 0xc8(%rsp), %rdi
leaq 0x38(%rsp), %rdx
callq 0x16708
jmp 0x1598b
leaq 0x128(%rsp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x73e0
leaq 0x58(%rsp), %rsi
movq %rsi, 0x48(%rsp)
movq (%rax), %rdx
leaq 0x10(%rax), %rcx
cmpq %rcx, %rdx
je 0x15705
movq %rdx, 0x48(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x58(%rsp)
jmp 0x1570d
movupd (%rcx), %xmm0
movupd %xmm0, (%rsi)
movq %rax, %rdx
addq $0x8, %rdx
movq 0x8(%rax), %rsi
movq %rsi, 0x50(%rsp)
movq %rcx, (%rax)
movq $0x0, (%rdx)
movb $0x0, (%rcx)
leaq 0x48(%rsp), %rdi
leaq 0x417ab(%rip), %rsi     # 0x56ee1
callq 0x7690
leaq 0x198(%rsp), %rsi
movq %rsi, 0x188(%rsp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
movl 0x124(%rsp), %edi
je 0x15776
movq %rdx, 0x188(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x198(%rsp)
jmp 0x1577e
movupd (%rcx), %xmm0
movupd %xmm0, (%rsi)
movq 0xd0(%rsp), %rbp
xorps %xmm0, %xmm0
cvtsi2sdq 0x1b8(%rsp), %xmm0
movsd 0x41705(%rip), %xmm3    # 0x56ea0
divsd %xmm3, %xmm0
leal 0x1(%rbx), %edx
cvtsi2sdl 0x120(%rsp), %xmm1
divsd %xmm3, %xmm1
cvtsi2sd %edi, %xmm2
divsd %xmm3, %xmm2
movq 0x8(%rax), %rsi
movq %rsi, 0x190(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
subq $0x8, %rsp
movzbl %r15b, %r15d
movzbl %r13b, %r11d
movzwl 0x48(%rsp), %r10d
movzwl 0x4c(%rsp), %eax
movzwl %dx, %r9d
movq %rbp, %rdi
leaq 0x20(%rsp), %rsi
movl 0x10(%rsp), %edx
movq 0xf0(%rsp), %rcx
movq 0x1f8(%rsp), %r8
movsd 0x1b0(%rsp), %xmm3
leaq 0x190(%rsp), %r13
pushq %r13
pushq %r12
pushq %r15
pushq %r14
pushq 0x1d8(%rsp)
pushq 0x1f0(%rsp)
pushq 0x200(%rsp)
pushq 0x210(%rsp)
pushq 0x220(%rsp)
pushq 0x230(%rsp)
pushq %r11
pushq 0x248(%rsp)
pushq 0x148(%rsp)
pushq 0x160(%rsp)
pushq 0x170(%rsp)
pushq 0x180(%rsp)
pushq 0x190(%rsp)
pushq 0x1a0(%rsp)
pushq 0x1b0(%rsp)
pushq %r10
pushq %rax
callq 0x21ce4
addq $0xb0, %rsp
movq %rbp, 0x38(%rsp)
movq 0x188(%rsp), %rdi
leaq 0x198(%rsp), %rax
cmpq %rax, %rdi
movq 0x10(%rsp), %r12
leaq 0x28(%rsp), %r13
leaq 0x158(%rsp), %r15
je 0x158c6
callq 0x7370
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
leaq 0x78(%rsp), %rbp
je 0x158df
callq 0x7370
movq 0x128(%rsp), %rdi
leaq 0x138(%rsp), %rax
cmpq %rax, %rdi
je 0x158f9
callq 0x7370
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x15913
callq 0x7370
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x15922
callq 0x7370
movq 0xa8(%rsp), %rdi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rdi
je 0x1593c
callq 0x7370
movq 0x68(%rsp), %rdi
cmpq %rbp, %rdi
je 0x1594b
callq 0x7370
movq 0x148(%rsp), %rdi
cmpq %r15, %rdi
je 0x1595d
callq 0x7370
movq 0x60(%r12), %rsi
cmpq 0x68(%r12), %rsi
je 0x15979
movq 0x38(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x60(%r12)
jmp 0x1598b
movq 0xc8(%rsp), %rdi
leaq 0x38(%rsp), %rdx
callq 0x16708
callq 0x28018
movq 0x38(%rsp), %rsi
movq %rax, %rdi
callq 0x2808c
incl %ebx
movzwl %bx, %r14d
leaq 0x59bee(%rip), %rcx     # 0x6f598
movq (%rcx), %rax
movq 0x8(%rcx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r14, %rcx
ja 0x14cf1
movq 0x38(%r12), %rdi
movq 0xc8(%rsp), %rsi
callq 0x24f3c
movq 0xd8(%rsp), %rax
cmpl $0x0, 0x38(%rax)
jne 0x15a02
movq 0x50(%r12), %rdi
movq 0xc8(%rsp), %rsi
callq 0x259f4
movq 0x38(%r12), %rsi
movq 0x50(%r12), %rdi
callq 0x259fa
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x8, %edi
callq 0x71d0
leaq 0x414d1(%rip), %rcx     # 0x56ef6
movq %rcx, (%rax)
movq 0x59521(%rip), %rsi     # 0x6ef50
movq %rax, %rdi
xorl %edx, %edx
callq 0x75e0
movq %rax, %r14
jmp 0x15a58
movq %rax, %r14
jmp 0x15a6c
movq %rax, %r14
movq 0x218(%rsp), %rdi
cmpq %rbx, %rdi
je 0x15a58
callq 0x7370
movq 0x18(%rsp), %rdi
leaq 0x28(%rsp), %rax
cmpq %rax, %rdi
je 0x15a6c
callq 0x7370
jmp 0x15aab
jmp 0x15a70
movq %rax, %r14
movq %r15, %rdi
jmp 0x15d3e
movq %rax, %r14
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x15a92
callq 0x7370
jmp 0x15a92
movq %rax, %r14
movq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rax
cmpq %rax, %rdi
je 0x15aa6
callq 0x7370
jmp 0x15aab
movq %rax, %r14
movq %r15, %rdi
callq 0x7370
jmp 0x15bd7
movq %rax, %r14
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x15d7b
jmp 0x15d76
movq %rax, %r14
jmp 0x15d7b
jmp 0x15d45
jmp 0x15d45
movq %rax, %r14
jmp 0x15d1a
movq %rax, %r14
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x15bb1
jmp 0x15bac
movq %rax, %r14
jmp 0x15b83
movq %rax, %r14
movq 0x168(%rsp), %rdi
leaq 0x178(%rsp), %rax
cmpq %rax, %rdi
je 0x15b69
callq 0x7370
jmp 0x15b69
movq %rax, %r14
jmp 0x15ce5
movq %rax, %r14
jmp 0x15cb2
jmp 0x15c81
movq %rax, %r14
jmp 0x15c5b
movq %rax, %r14
jmp 0x15c2d
movq %rax, %r14
jmp 0x15d39
movq %rax, %r14
jmp 0x15d06
movq %rax, %r14
jmp 0x15bb1
movq %rax, %r14
jmp 0x15b9d
movq %rax, %r14
movq 0xa8(%rsp), %rdi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rdi
je 0x15b83
callq 0x7370
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x15b9d
callq 0x7370
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x15bb1
callq 0x7370
movq 0x1f8(%rsp), %rdi
leaq 0x208(%rsp), %rax
cmpq %rax, %rdi
je 0x15cf2
callq 0x7370
jmp 0x15cf2
movq %rax, %r14
movq 0x10(%rsp), %r12
jmp 0x15d48
movq %rax, %r14
jmp 0x15cc6
movq %rax, %r14
jmp 0x15c98
movq %rax, %r14
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x15c84
jmp 0x15c70
movq %rax, %r14
jmp 0x15c41
movq %rax, %r14
movq 0x188(%rsp), %rdi
leaq 0x198(%rsp), %rax
cmpq %rax, %rdi
je 0x15c2d
callq 0x7370
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x15c41
callq 0x7370
movq 0x128(%rsp), %rdi
leaq 0x138(%rsp), %rax
cmpq %rax, %rdi
je 0x15c5b
callq 0x7370
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x15c84
callq 0x7370
jmp 0x15c84
jmp 0x15d45
jmp 0x15d45
movq %rax, %r14
movq 0x18(%rsp), %rdi
leaq 0x28(%rsp), %rax
cmpq %rax, %rdi
je 0x15c98
callq 0x7370
movq 0xa8(%rsp), %rdi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rdi
je 0x15cb2
callq 0x7370
movq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rax
cmpq %rax, %rdi
je 0x15cc6
callq 0x7370
movq 0x148(%rsp), %rdi
leaq 0x158(%rsp), %rax
cmpq %rax, %rdi
je 0x15ce0
callq 0x7370
movq 0x10(%rsp), %r12
movq 0xd0(%rsp), %rdi
jmp 0x15d3e
movq %rax, %r14
movq 0x18(%rsp), %rdi
leaq 0x28(%rsp), %rax
cmpq %rax, %rdi
je 0x15d06
callq 0x7370
movq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rax
cmpq %rax, %rdi
je 0x15d1a
callq 0x7370
movq 0x148(%rsp), %rdi
leaq 0x158(%rsp), %rax
cmpq %rax, %rdi
je 0x15d34
callq 0x7370
movq 0x10(%rsp), %r12
movq 0x8(%rsp), %rdi
callq 0x7370
jmp 0x15d48
movq %rax, %r14
movq 0xc8(%rsp), %rax
movq (%rax), %rdi
testq %rdi, %rdi
je 0x15d5d
callq 0x7370
leaq 0x57d04(%rip), %rax     # 0x6da68
movq %rax, (%r12)
movq 0x8(%r12), %rdi
addq $0x18, %r12
cmpq %r12, %rdi
je 0x15d7b
callq 0x7370
movq %r14, %rdi
callq 0x7620
nop