// File: /workspace/github_cpp_makefile_star2_O3/CMU-SAFARI[P]MQSim/src/ssd/Data_Cache_Manager_Flash_Advanced.cpp
// Function: SSD_Components::Data_Cache_Manager_Flash_Advanced::Execute_simulator_event(MQSimEngine::Sim_Event*)
void Data_Cache_Manager_Flash_Advanced::Execute_simulator_event(MQSimEngine::Sim_Event* ev)
	{
		Data_Cache_Simulation_Event_Type eventType = (Data_Cache_Simulation_Event_Type)ev->Type;
		Memory_Transfer_Info* transfer_info = (Memory_Transfer_Info*)ev->Parameters;

		switch (eventType)
		{
			case Data_Cache_Simulation_Event_Type::MEMORY_READ_FOR_USERIO_FINISHED://A user read is service from DRAM cache
			case Data_Cache_Simulation_Event_Type::MEMORY_WRITE_FOR_USERIO_FINISHED:
				((User_Request*)(transfer_info)->Related_request)->Sectors_serviced_from_cache -= transfer_info->Size_in_bytes / SECTOR_SIZE_IN_BYTE;
				if (is_user_request_finished((User_Request*)(transfer_info)->Related_request))
					broadcast_user_request_serviced_signal(((User_Request*)(transfer_info)->Related_request));
				break;
			case Data_Cache_Simulation_Event_Type::MEMORY_READ_FOR_CACHE_EVICTION_FINISHED://Reading data from DRAM and writing it back to the flash storage
				static_cast<FTL*>(nvm_firmware)->Address_Mapping_Unit->Translate_lpa_to_ppa_and_dispatch(*((std::list<NVM_Transaction*>*)(transfer_info->Related_request)));
				delete (std::list<NVM_Transaction*>*)transfer_info->Related_request;
				break;
			case Data_Cache_Simulation_Event_Type::MEMORY_WRITE_FOR_CACHE_FINISHED://The recently read data from flash is written back to memory to support future user read requests
				break;
		}
		delete transfer_info;

		memory_channel_is_busy = false;
		if (shared_dram_request_queue)	{
			if (dram_execution_queue[0].size() > 0)	{
				Memory_Transfer_Info* transfer_info = dram_execution_queue[0].front();
				dram_execution_queue[0].pop();
				Simulator->Register_sim_event(Simulator->Time() + estimate_dram_access_time(transfer_info->Size_in_bytes, dram_row_size, dram_busrt_size,
					dram_burst_transfer_time_ddr, dram_tRCD, dram_tCL, dram_tRP),
					this, transfer_info, static_cast<int>(transfer_info->next_event_type));
				memory_channel_is_busy = true;
			}
		} else {
			for (unsigned int i = 0; i < stream_count; i++) {
				dram_execution_list_turn++;
				dram_execution_list_turn %= stream_count;
				if (dram_execution_queue[dram_execution_list_turn].size() > 0) {
					Memory_Transfer_Info* transfer_info = dram_execution_queue[dram_execution_list_turn].front();
					dram_execution_queue[dram_execution_list_turn].pop();
					Simulator->Register_sim_event(Simulator->Time() + estimate_dram_access_time(transfer_info->Size_in_bytes, dram_row_size, dram_busrt_size,
						dram_burst_transfer_time_ddr, dram_tRCD, dram_tCL, dram_tRP),
						this, transfer_info, static_cast<int>(transfer_info->next_event_type));
					memory_channel_is_busy = true;
					break;
				}
			}
		}
	}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movl 0x18(%rsi), %eax
movq 0x10(%rsi), %r14
leal -0x2(%rax), %ecx
cmpl $0x2, %ecx
jae 0x3416b
movl (%r14), %eax
shrl $0x9, %eax
movq 0x8(%r14), %rsi
movl 0x58(%rsi), %ecx
cmpq $0x0, 0x50(%rsi)
sete %dl
subl %eax, %ecx
movl %ecx, 0x58(%rsi)
sete %al
andb %dl, %al
cmpb $0x1, %al
jne 0x341aa
movq %rbx, %rdi
callq 0x321ee
jmp 0x341aa
testl %eax, %eax
jne 0x341aa
movq 0x38(%rbx), %rax
movq 0x38(%rax), %rdi
movq 0x8(%r14), %rsi
movq (%rdi), %rax
callq *0x60(%rax)
movq 0x8(%r14), %r15
testq %r15, %r15
je 0x341a2
movq (%r15), %rdi
cmpq %r15, %rdi
je 0x341a2
movq (%rdi), %r12
callq 0x7370
movq %r12, %rdi
cmpq %r15, %r12
jne 0x34192
movq %r15, %rdi
callq 0x7370
movq %r14, %rdi
callq 0x7370
movb $0x0, 0xc8(%rbx)
cmpb $0x0, 0xe0(%rbx)
je 0x34213
movq 0xd0(%rbx), %rdi
movq 0x48(%rdi), %rax
movq %rax, %rcx
subq 0x28(%rdi), %rcx
shrq $0x3, %rcx
cmpq $0x1, %rax
adcq $-0x1, %rcx
movq 0x30(%rdi), %rdx
subq 0x38(%rdi), %rdx
shlq $0x6, %rcx
sarq $0x3, %rdx
addq %rcx, %rdx
movq 0x10(%rdi), %rax
movq 0x20(%rdi), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
addq %rdx, %rcx
je 0x3448e
movq (%rax), %r14
jmp 0x3429f
movl 0x74(%rbx), %ecx
testl %ecx, %ecx
je 0x3448e
movq 0xd0(%rbx), %rdi
movl 0xe4(%rbx), %edx
movl %ecx, %esi
incl %edx
movl %edx, %eax
xorl %edx, %edx
divl %ecx
movslq %edx, %rax
leaq (%rax,%rax,4), %rax
shlq $0x4, %rax
movq 0x48(%rdi,%rax), %r8
movq %r8, %r9
subq 0x28(%rdi,%rax), %r9
shrq $0x3, %r9
cmpq $0x1, %r8
adcq $-0x1, %r9
movq 0x30(%rdi,%rax), %r10
subq 0x38(%rdi,%rax), %r10
shlq $0x6, %r9
sarq $0x3, %r10
addq %r9, %r10
movq 0x10(%rdi,%rax), %r8
movq 0x20(%rdi,%rax), %r9
subq %r8, %r9
sarq $0x3, %r9
addq %r10, %r9
jne 0x34293
decl %esi
jne 0x3422d
movl %edx, 0xe4(%rbx)
jmp 0x3448e
addq %rax, %rdi
movl %edx, 0xe4(%rbx)
movq (%r8), %r14
callq 0x3470a
callq 0x28018
movq %rax, %r15
callq 0x28018
movq %rax, %rdi
callq 0x2841a
movq %rax, %rcx
movl (%r14), %edi
movl 0x40(%rbx), %r8d
movl 0x48(%rbx), %r10d
movsd 0x50(%rbx), %xmm0
movq 0x58(%rbx), %r12
movq 0x60(%rbx), %r11
leaq (%r11,%r12), %rsi
cmpl %r8d, %edi
jbe 0x3443f
movl %r8d, %eax
xorl %edx, %edx
divl %r10d
movl %eax, %r9d
movq 0x68(%rbx), %xmm3
movl %edi, %eax
xorl %edx, %edx
divl %r8d
movq %rsi, %xmm5
movq 0x235bb(%rip), %xmm1    # 0x578c0
punpckldq %xmm1, %xmm5    # xmm5 = xmm5[0],xmm1[0],xmm5[1],xmm1[1]
movapd 0x235bf(%rip), %xmm2    # 0x578d0
subpd %xmm2, %xmm5
movapd %xmm5, %xmm4
unpckhpd %xmm5, %xmm4            # xmm4 = xmm4[1],xmm5[1]
addsd %xmm5, %xmm4
shrl %r9d
xorps %xmm5, %xmm5
cvtsi2sd %r9d, %xmm5
punpckldq %xmm1, %xmm3    # xmm3 = xmm3[0],xmm1[0],xmm3[1],xmm1[1]
subpd %xmm2, %xmm3
movapd %xmm3, %xmm6
unpckhpd %xmm3, %xmm6            # xmm6 = xmm6[1],xmm3[1]
addsd %xmm3, %xmm6
mulsd %xmm0, %xmm5
addsd %xmm6, %xmm5
cvttsd2si %xmm5, %rsi
movq %rsi, %rdi
sarq $0x3f, %rdi
movsd 0x20cf4(%rip), %xmm3    # 0x55050
subsd %xmm3, %xmm5
cvttsd2si %xmm5, %r8
andq %rdi, %r8
orq %rsi, %r8
movq %r8, %xmm5
punpckldq %xmm1, %xmm5    # xmm5 = xmm5[0],xmm1[0],xmm5[1],xmm1[1]
subpd %xmm2, %xmm5
movapd %xmm5, %xmm6
unpckhpd %xmm5, %xmm6            # xmm6 = xmm6[1],xmm5[1]
addsd %xmm5, %xmm6
shrl %eax
xorps %xmm5, %xmm5
cvtsi2sd %eax, %xmm5
mulsd %xmm6, %xmm5
addsd %xmm4, %xmm5
movq %r12, %xmm4
punpckldq %xmm1, %xmm4    # xmm4 = xmm4[0],xmm1[0],xmm4[1],xmm1[1]
subpd %xmm2, %xmm4
movapd %xmm4, %xmm6
unpckhpd %xmm4, %xmm6            # xmm6 = xmm6[1],xmm4[1]
addsd %xmm4, %xmm6
addsd %xmm5, %xmm6
movq %r11, %xmm5
punpckldq %xmm1, %xmm5    # xmm5 = xmm5[0],xmm1[0],xmm5[1],xmm1[1]
subpd %xmm2, %xmm5
movapd %xmm5, %xmm4
unpckhpd %xmm5, %xmm4            # xmm4 = xmm4[1],xmm5[1]
addsd %xmm5, %xmm4
xorps %xmm5, %xmm5
cvtsi2sd %rdx, %xmm5
addsd %xmm6, %xmm4
movl %r10d, %eax
xorps %xmm6, %xmm6
cvtsi2sd %rax, %xmm6
mulsd %xmm0, %xmm6
divsd %xmm6, %xmm5
cvttsd2si %xmm5, %rax
movq %rax, %rdx
subsd %xmm3, %xmm5
cvttsd2si %xmm5, %rsi
sarq $0x3f, %rdx
andq %rdx, %rsi
orq %rax, %rsi
movq %rsi, %xmm0
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
subpd %xmm2, %xmm0
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
addsd %xmm4, %xmm1
cvttsd2si %xmm1, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
subsd %xmm3, %xmm1
cvttsd2si %xmm1, %rsi
andq %rdx, %rsi
orq %rax, %rsi
jmp 0x34472
movl %edi, %eax
xorl %edx, %edx
divl %r10d
shrl %eax
cvtsi2sd %eax, %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movq %rax, %rdx
subsd 0x20bf0(%rip), %xmm0    # 0x55050
cvttsd2si %xmm0, %rdi
sarq $0x3f, %rdx
andq %rdx, %rdi
orq %rax, %rdi
addq %rdi, %rsi
addq %rcx, %rsi
movl 0x10(%r14), %r8d
movq %r15, %rdi
movq %rbx, %rdx
movq %r14, %rcx
callq 0x2841e
movb $0x1, 0xc8(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq