// File: /workspace/github_cpp_makefile_star2_O1/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 0x423bf(%rip), %rsi     # 0x56ea8
leaq 0x423bc(%rip), %rdx     # 0x56eac
leaq 0x18(%rsp), %rdi
callq 0xb0c6
leaq 0x18(%rsp), %rsi
movq %r12, %rdi
callq 0x165ce
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x14b16
callq 0x7370
leaq 0x58e93(%rip), %rax     # 0x6d9b0
movq %rax, (%r12)
leaq 0x58ec0(%rip), %rax     # 0x6d9e8
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 0x281b4
movq %rax, %rdi
movq %r12, %rsi
callq 0x2822a
cmpl $0x0, 0x38(%r14)
movq %r12, 0x10(%rsp)
je 0x14b7d
movq $0x0, 0x50(%r12)
jmp 0x14c59
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 0xb036
leaq 0x42302(%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 0x14be5
movq %rdx, 0x218(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x228(%rsp)
jmp 0x14bed
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 0x4545e
leaq 0x5a951(%rip), %rcx     # 0x6f568
movq (%rcx), %rcx
movzwl %ax, %edx
leaq 0x218(%rsp), %rsi
movq %r15, %rdi
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0x25134
movq %r15, 0x50(%r12)
movq 0x218(%rsp), %rdi
cmpq %rbx, %rdi
je 0x14c4a
callq 0x7370
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x14c59
callq 0x7370
movl $0x100, %edi            # imm = 0x100
callq 0x73a0
movq %rax, %r15
leaq 0xb8(%rsp), %rbp
movq %rbp, -0x10(%rbp)
movq 0x8(%r12), %rsi
movq 0x10(%r12), %rdx
addq %rsi, %rdx
leaq 0xa8(%rsp), %rdi
callq 0xb036
leaq 0x42224(%rip), %rsi     # 0x56eb7
leaq 0xa8(%rsp), %rdi
callq 0x7690
movq %r13, 0x18(%rsp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x14cc3
movq %rdx, 0x18(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x28(%rsp)
jmp 0x14ccd
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 0x5a7a8(%rip), %rax     # 0x6f498
movsd (%rax), %xmm0
leaq 0x5a7a5(%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 0x246b4
addq $0x20, %rsp
movq %r15, 0x40(%r12)
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x14d35
callq 0x7370
movq 0xa8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x14d47
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 0x24f54
movq %r15, 0x38(%r12)
movq 0x40(%r12), %rdi
movq %r15, %rsi
callq 0x247c4
movl $0x10, %edi
callq 0x73a0
movq %rax, %r15
movq 0x40(%r12), %rsi
movq %rax, %rdi
movq %r14, %rdx
callq 0x250d4
movq %r15, 0x48(%r12)
movq 0x40(%r12), %rdi
movq %r15, %rsi
callq 0x247ca
callq 0x281b4
movq 0x40(%r12), %rsi
movq %rax, %rdi
callq 0x2822a
movq %r14, 0xd8(%rsp)
movq %r14, %rdi
callq 0x411dc
leaq 0x5a7c1(%rip), %rcx     # 0x6f598
movq 0x8(%rcx), %rax
cmpq (%rcx), %rax
je 0x15ac1
leaq 0x158(%rsp), %r15
xorl %r14d, %r14d
xorl %ebx, %ebx
movq $0x0, 0x38(%rsp)
movq 0xd8(%rsp), %rdi
cmpl $0x1, 0x38(%rdi)
jne 0x14e24
callq 0x4261a
movl %eax, 0x44(%rsp)
movq 0xd8(%rsp), %rdi
callq 0x42622
movl %eax, 0x40(%rsp)
jmp 0x14e34
movl $0x0, 0x44(%rsp)
movl $0x0, 0x40(%rsp)
leaq 0x5a75d(%rip), %rax     # 0x6f598
movq (%rax), %rax
movq (%rax,%r14,8), %r14
movl 0xc(%r14), %eax
cmpl $0x1, %eax
je 0x14eec
testl %eax, %eax
jne 0x15b14
movl 0x4c(%r14), %eax
addl $-0x65, %eax
cmpl $-0x65, %eax
ja 0x14e6b
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 0xb036
movq %r15, %rdi
leaq 0x42015(%rip), %rsi     # 0x56ec1
callq 0x7690
leaq 0x98(%rsp), %r15
movq %rbp, 0xa8(%rsp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x14fbe
movq %rdx, 0xa8(%rsp)
movq (%rcx), %rdx
movq %rdx, 0xb8(%rsp)
jmp 0x14fc7
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 0xb036
movq %r15, %rdi
leaq 0x41fbc(%rip), %rsi     # 0x56ee6
callq 0x7690
movq %rbp, 0xa8(%rsp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x14f5b
movq %rdx, 0xa8(%rsp)
movq (%rcx), %rdx
movq %rdx, 0xb8(%rsp)
jmp 0x14f64
movupd (%rcx), %xmm0
movupd %xmm0, (%rbp)
movq 0x8(%rax), %rdx
movq %rdx, 0xb0(%rsp)
movq %rcx, (%rax)
movq $0x0, 0x8(%rax)
movb $0x0, 0x10(%rax)
movq 0x50(%r14), %rsi
movq 0x58(%r14), %rdx
leaq 0xa8(%rsp), %rdi
callq 0x7130
movq %r13, 0x18(%rsp)
movq (%rax), %rdx
movq %rax, %rcx
addq $0x10, %rcx
cmpq %rcx, %rdx
je 0x150c7
movq %rdx, 0x18(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x28(%rsp)
jmp 0x150d1
movupd (%rcx), %xmm0
movupd %xmm0, (%rbp)
movq 0x8(%rax), %rdx
movq %rdx, 0xb0(%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 0x1501e
movl $0x2, %ebp
cmpw $0x64, %bx
jb 0x1501e
movl $0x3, %ebp
cmpl $0x3e8, 0x8(%rsp)       # imm = 0x3E8
jb 0x1501e
cmpl $0x2710, 0x8(%rsp)      # imm = 0x2710
movl $0x5, %ebp
sbbl $0x0, %ebp
movl %ebp, %esi
movq %r15, 0x88(%rsp)
leaq 0x88(%rsp), %rdi
movl $0x2d, %edx
callq 0x7420
movq 0x88(%rsp), %rdi
movl %ebp, %esi
movl 0x8(%rsp), %edx
callq 0xafc9
movq 0xa8(%rsp), %rcx
movl $0xf, %esi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rcx
je 0x1506f
movq 0xb8(%rsp), %rsi
movq 0xb0(%rsp), %r8
movq 0x90(%rsp), %rdx
leaq (%rdx,%r8), %rax
cmpq %rsi, %rax
leaq 0x68(%rsp), %rbp
jbe 0x150ad
movl $0xf, %esi
cmpq %r15, 0x88(%rsp)
je 0x150a4
movq 0x98(%rsp), %rsi
cmpq %rsi, %rax
jbe 0x152b5
movq 0x88(%rsp), %rsi
leaq 0xa8(%rsp), %rdi
callq 0x7130
jmp 0x152c6
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 0x538c4
movq %rax, 0xd0(%rsp)
movl %r15d, %edi
callq 0x5392a
movq %rax, 0x118(%rsp)
movl 0x10(%r14), %eax
movq %rax, 0x110(%rsp)
movl 0x38(%r14), %eax
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
divsd 0x41d73(%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 0xb036
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 0x5a3c2(%rip), %rax     # 0x6f570
movb (%rax), %r13b
leaq 0x5a2f0(%rip), %rax     # 0x6f4a8
movq (%rax), %rbp
leaq 0x58(%rsp), %rax
movq %rax, 0x48(%rsp)
leaq 0x5a3ac(%rip), %rax     # 0x6f578
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
leaq 0x48(%rsp), %r14
movq %r14, %rdi
callq 0xb036
movq %r14, %rdi
leaq 0x41ce7(%rip), %rsi     # 0x56ed4
callq 0x7690
movl $0x1, %r14d
cmpw $0xa, %bx
jb 0x1522a
movl $0x2, %r14d
cmpw $0x64, %bx
jb 0x1522a
movl $0x3, %r14d
cmpl $0x3e8, %r15d           # imm = 0x3E8
jb 0x1522a
cmpl $0x2710, %r15d          # imm = 0x2710
movl $0x5, %r14d
sbbl $0x0, %r14d
movl %r14d, %esi
leaq 0x78(%rsp), %rax
movq %rax, 0x68(%rsp)
leaq 0x68(%rsp), %rdi
movl $0x2d, %edx
callq 0x7420
movq 0x68(%rsp), %rdi
movl %r14d, %esi
movl %r15d, %edx
callq 0xafc9
movq 0x48(%rsp), %rcx
movl $0xf, %esi
leaq 0x58(%rsp), %rax
cmpq %rax, %rcx
je 0x1526f
movq 0x58(%rsp), %rsi
movq 0x50(%rsp), %r8
movq 0x70(%rsp), %rdx
leaq (%rdx,%r8), %rax
cmpq %rsi, %rax
jbe 0x152a1
movl $0xf, %esi
leaq 0x78(%rsp), %rdi
cmpq %rdi, 0x68(%rsp)
je 0x15298
movq 0x78(%rsp), %rsi
cmpq %rsi, %rax
jbe 0x1557e
movq 0x68(%rsp), %rsi
leaq 0x48(%rsp), %rdi
callq 0x7130
jmp 0x1558c
leaq 0x88(%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 0x152e6
movq %rdx, 0x18(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x28(%rsp)
jmp 0x152f0
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 0x538c4
movq %rax, %r13
movl %r15d, %edi
callq 0x5392a
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 0x153ca
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 0x153d6
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 0x41a7f(%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 0x5a10b(%rip), %rax     # 0x6f570
movb (%rax), %r15b
leaq 0x5a039(%rip), %rax     # 0x6f4a8
movq (%rax), %r12
leaq 0x78(%rsp), %rax
movq %rax, 0x68(%rsp)
leaq 0x5a0f5(%rip), %rax     # 0x6f578
movq (%rax), %rsi
movq 0x8(%rax), %rdx
addq %rsi, %rdx
movq %rbp, %rdi
callq 0xb036
movq %rbp, %rdi
leaq 0x41a35(%rip), %rsi     # 0x56ed4
callq 0x7690
movl $0x1, %ebp
cmpw $0xa, %bx
jb 0x154d9
movl $0x2, %ebp
cmpw $0x64, %bx
jb 0x154d9
movl $0x3, %ebp
cmpl $0x3e8, 0x8(%rsp)       # imm = 0x3E8
jb 0x154d9
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 0xafc9
movq 0x68(%rsp), %rcx
movl $0xf, %esi
leaq 0x78(%rsp), %rax
cmpq %rax, %rcx
je 0x15529
movq 0x78(%rsp), %rsi
movq 0x70(%rsp), %r8
movq 0x130(%rsp), %rdx
leaq (%rdx,%r8), %rax
cmpq %rsi, %rax
jbe 0x15567
movl $0xf, %esi
leaq 0x138(%rsp), %rdi
cmpq %rdi, 0x128(%rsp)
je 0x1555e
movq 0x138(%rsp), %rsi
cmpq %rsi, %rax
jbe 0x157d2
movq 0x128(%rsp), %rsi
leaq 0x68(%rsp), %rdi
callq 0x7130
jmp 0x157e3
leaq 0x68(%rsp), %rdi
xorl %esi, %esi
xorl %edx, %edx
callq 0x73e0
leaq 0x98(%rsp), %rsi
movq %rsi, 0x88(%rsp)
movq (%rax), %rdx
leaq 0x10(%rax), %rcx
cmpq %rcx, %rdx
je 0x155bd
movq %rdx, 0x88(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x98(%rsp)
jmp 0x155c5
movupd (%rcx), %xmm0
movupd %xmm0, (%rsi)
movq %rax, %rdx
addq $0x8, %rdx
movq 0x8(%rax), %rsi
movq %rsi, 0x90(%rsp)
movq %rcx, (%rax)
movq $0x0, (%rdx)
movb $0x0, (%rcx)
leaq 0x88(%rsp), %rdi
leaq 0x418ed(%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 0x1562d
movq %rdx, 0x168(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x178(%rsp)
jmp 0x15635
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 0x22a04
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 0xb8(%rsp), %rbp
leaq 0x158(%rsp), %r15
je 0x1571c
callq 0x7370
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x15736
callq 0x7370
movq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rax
cmpq %rax, %rdi
je 0x1574a
callq 0x7370
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x1575e
callq 0x7370
movq 0x1f8(%rsp), %rdi
leaq 0x208(%rsp), %rax
cmpq %rax, %rdi
je 0x15778
callq 0x7370
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x15787
callq 0x7370
movq 0xa8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x15799
callq 0x7370
movq 0x148(%rsp), %rdi
cmpq %r15, %rdi
je 0x157ab
callq 0x7370
movq 0x60(%r12), %rsi
cmpq 0x68(%r12), %rsi
jne 0x15a6c
movq 0xc8(%rsp), %rdi
leaq 0x38(%rsp), %rdx
callq 0x16802
jmp 0x15a8e
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 0x15808
movq %rdx, 0x48(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x58(%rsp)
jmp 0x15810
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 0x416a8(%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 0x15879
movq %rdx, 0x188(%rsp)
movq (%rcx), %rdx
movq %rdx, 0x198(%rsp)
jmp 0x15881
movupd (%rcx), %xmm0
movupd %xmm0, (%rsi)
movq 0xd0(%rsp), %rbp
xorps %xmm0, %xmm0
cvtsi2sdq 0x1b8(%rsp), %xmm0
movsd 0x41602(%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 0x21dd0
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 0x159c9
callq 0x7370
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
leaq 0xb8(%rsp), %rbp
je 0x159e5
callq 0x7370
movq 0x128(%rsp), %rdi
leaq 0x138(%rsp), %rax
cmpq %rax, %rdi
je 0x159ff
callq 0x7370
movq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rax
cmpq %rax, %rdi
je 0x15a13
callq 0x7370
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x15a22
callq 0x7370
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x15a3c
callq 0x7370
movq 0xa8(%rsp), %rdi
cmpq %rbp, %rdi
je 0x15a4e
callq 0x7370
movq 0x148(%rsp), %rdi
cmpq %r15, %rdi
je 0x15a60
callq 0x7370
movq 0x60(%r12), %rsi
cmpq 0x68(%r12), %rsi
je 0x15a7c
movq 0x38(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x60(%r12)
jmp 0x15a8e
movq 0xc8(%rsp), %rdi
leaq 0x38(%rsp), %rdx
callq 0x16802
callq 0x281b4
movq 0x38(%rsp), %rsi
movq %rax, %rdi
callq 0x2822a
incl %ebx
movzwl %bx, %r14d
leaq 0x59aeb(%rip), %rcx     # 0x6f598
movq 0x8(%rcx), %rax
subq (%rcx), %rax
sarq $0x3, %rax
cmpq %r14, %rax
ja 0x14df1
movq 0x38(%r12), %rdi
movq 0xc8(%rsp), %rsi
callq 0x250cc
movq 0xd8(%rsp), %rax
cmpl $0x0, 0x38(%rax)
jne 0x15b02
movq 0x50(%r12), %rdi
movq 0xc8(%rsp), %rsi
callq 0x25b84
movq 0x38(%r12), %rsi
movq 0x50(%r12), %rdi
callq 0x25b8a
addq $0x238, %rsp            # imm = 0x238
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x8, %edi
callq 0x71d0
leaq 0x413d1(%rip), %rcx     # 0x56ef6
movq %rcx, (%rax)
movq 0x59429(%rip), %rsi     # 0x6ef58
movq %rax, %rdi
xorl %edx, %edx
callq 0x75e0
movq %rax, %r14
jmp 0x15b58
movq %rax, %r14
jmp 0x15b6c
movq %rax, %r14
movq 0x218(%rsp), %rdi
cmpq %rbx, %rdi
je 0x15b58
callq 0x7370
movq 0x18(%rsp), %rdi
leaq 0x28(%rsp), %rax
cmpq %rax, %rdi
je 0x15b6c
callq 0x7370
jmp 0x15bb1
jmp 0x15b70
movq %rax, %r14
movq %r15, %rdi
jmp 0x15e3e
movq %rax, %r14
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x15b92
callq 0x7370
jmp 0x15b92
movq %rax, %r14
movq 0xa8(%rsp), %rdi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rdi
je 0x15bac
callq 0x7370
jmp 0x15bb1
movq %rax, %r14
movq %r15, %rdi
callq 0x7370
jmp 0x15cd7
movq %rax, %r14
movq 0x18(%rsp), %rdi
cmpq %r13, %rdi
je 0x15e7b
jmp 0x15e76
movq %rax, %r14
jmp 0x15e7b
jmp 0x15e45
jmp 0x15e45
movq %rax, %r14
jmp 0x15e1a
movq %rax, %r14
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x15cb1
jmp 0x15cac
movq %rax, %r14
jmp 0x15c89
movq %rax, %r14
movq 0x168(%rsp), %rdi
leaq 0x178(%rsp), %rax
cmpq %rax, %rdi
je 0x15c6f
callq 0x7370
jmp 0x15c6f
movq %rax, %r14
jmp 0x15ddf
movq %rax, %r14
jmp 0x15da6
jmp 0x15d75
movq %rax, %r14
jmp 0x15d55
movq %rax, %r14
jmp 0x15d27
movq %rax, %r14
jmp 0x15e39
movq %rax, %r14
jmp 0x15e00
movq %rax, %r14
jmp 0x15cb1
movq %rax, %r14
jmp 0x15c9d
movq %rax, %r14
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x15c89
callq 0x7370
movq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rax
cmpq %rax, %rdi
je 0x15c9d
callq 0x7370
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x15cb1
callq 0x7370
movq 0x1f8(%rsp), %rdi
leaq 0x208(%rsp), %rax
cmpq %rax, %rdi
je 0x15dec
callq 0x7370
jmp 0x15dec
movq %rax, %r14
movq 0x10(%rsp), %r12
jmp 0x15e48
movq %rax, %r14
jmp 0x15dc0
movq %rax, %r14
jmp 0x15d8c
movq %rax, %r14
movq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rax
cmpq %rax, %rdi
je 0x15d78
jmp 0x15d64
movq %rax, %r14
jmp 0x15d3b
movq %rax, %r14
movq 0x188(%rsp), %rdi
leaq 0x198(%rsp), %rax
cmpq %rax, %rdi
je 0x15d27
callq 0x7370
movq 0x48(%rsp), %rdi
leaq 0x58(%rsp), %rax
cmpq %rax, %rdi
je 0x15d3b
callq 0x7370
movq 0x128(%rsp), %rdi
leaq 0x138(%rsp), %rax
cmpq %rax, %rdi
je 0x15d55
callq 0x7370
movq 0x68(%rsp), %rdi
leaq 0x78(%rsp), %rax
cmpq %rax, %rdi
je 0x15d78
callq 0x7370
jmp 0x15d78
jmp 0x15e45
jmp 0x15e45
movq %rax, %r14
movq 0x18(%rsp), %rdi
leaq 0x28(%rsp), %rax
cmpq %rax, %rdi
je 0x15d8c
callq 0x7370
movq 0x88(%rsp), %rdi
leaq 0x98(%rsp), %rax
cmpq %rax, %rdi
je 0x15da6
callq 0x7370
movq 0xa8(%rsp), %rdi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rdi
je 0x15dc0
callq 0x7370
movq 0x148(%rsp), %rdi
leaq 0x158(%rsp), %rax
cmpq %rax, %rdi
je 0x15dda
callq 0x7370
movq 0x10(%rsp), %r12
movq 0xd0(%rsp), %rdi
jmp 0x15e3e
movq %rax, %r14
movq 0x18(%rsp), %rdi
leaq 0x28(%rsp), %rax
cmpq %rax, %rdi
je 0x15e00
callq 0x7370
movq 0xa8(%rsp), %rdi
leaq 0xb8(%rsp), %rax
cmpq %rax, %rdi
je 0x15e1a
callq 0x7370
movq 0x148(%rsp), %rdi
leaq 0x158(%rsp), %rax
cmpq %rax, %rdi
je 0x15e34
callq 0x7370
movq 0x10(%rsp), %r12
movq 0x8(%rsp), %rdi
callq 0x7370
jmp 0x15e48
movq %rax, %r14
movq 0xc8(%rsp), %rax
movq (%rax), %rdi
testq %rdi, %rdi
je 0x15e5d
callq 0x7370
leaq 0x57bf4(%rip), %rax     # 0x6da58
movq %rax, (%r12)
movq 0x8(%r12), %rdi
addq $0x18, %r12
cmpq %r12, %rdi
je 0x15e7b
callq 0x7370
movq %r14, %rdi
callq 0x7620
nop