// 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::handle_transaction_serviced_signal_from_PHY(SSD_Components::NVM_Transaction_Flash*)
void Data_Cache_Manager_Flash_Advanced::handle_transaction_serviced_signal_from_PHY(NVM_Transaction_Flash* transaction)
	{
		//First check if the transaction source is a user request or the cache itself
		if (transaction->Source != Transaction_Source_Type::USERIO && transaction->Source != Transaction_Source_Type::CACHE) {
			return;
		}

		if (transaction->Source == Transaction_Source_Type::USERIO) {
			_my_instance->broadcast_user_memory_transaction_serviced_signal(transaction);
		}

		/* This is an update read (a read that is generated for a write request that partially updates page data).
		*  An update read transaction is issued in Address Mapping Unit, but is consumed in data cache manager.*/
		if (transaction->Type == Transaction_Type::READ) {
			if (((NVM_Transaction_Flash_RD*)transaction)->RelatedWrite != NULL) {
				((NVM_Transaction_Flash_RD*)transaction)->RelatedWrite->RelatedRead = NULL;
				return;
			}

			switch (Data_Cache_Manager_Flash_Advanced::caching_mode_per_input_stream[transaction->Stream_id])
			{
				case Caching_Mode::TURNED_OFF:
				case Caching_Mode::WRITE_CACHE:
					transaction->UserIORequest->Transaction_list.remove(transaction);
					if (_my_instance->is_user_request_finished(transaction->UserIORequest)) {
						_my_instance->broadcast_user_request_serviced_signal(transaction->UserIORequest);
					}
					break;
				case Caching_Mode::READ_CACHE:
				case Caching_Mode::WRITE_READ_CACHE:
				{					
					if (((Data_Cache_Manager_Flash_Advanced*)_my_instance)->per_stream_cache[transaction->Stream_id]->Exists(transaction->Stream_id, transaction->LPA)) {
						/*MQSim should get rid of writting stale data to the cache.
						* This situation may result from out-of-order transaction execution*/
						Data_Cache_Slot_Type slot = ((Data_Cache_Manager_Flash_Advanced*)_my_instance)->per_stream_cache[transaction->Stream_id]->Get_slot(transaction->Stream_id, transaction->LPA);
						sim_time_type timestamp = slot.Timestamp;
						NVM::memory_content_type content = slot.Content;
						if (((NVM_Transaction_Flash_RD*)transaction)->DataTimeStamp > timestamp) {
							timestamp = ((NVM_Transaction_Flash_RD*)transaction)->DataTimeStamp;
							content = ((NVM_Transaction_Flash_RD*)transaction)->Content;
						}

						((Data_Cache_Manager_Flash_Advanced*)_my_instance)->per_stream_cache[transaction->Stream_id]->Update_data(transaction->Stream_id, transaction->LPA, content,
							timestamp, ((NVM_Transaction_Flash_RD*)transaction)->read_sectors_bitmap | slot.State_bitmap_of_existing_sectors);
					} else  {
						if (!((Data_Cache_Manager_Flash_Advanced*)_my_instance)->per_stream_cache[transaction->Stream_id]->Check_free_slot_availability()) {
							std::list<NVM_Transaction*>* evicted_cache_slots = new std::list<NVM_Transaction*>;
							Data_Cache_Slot_Type evicted_slot = ((Data_Cache_Manager_Flash_Advanced*)_my_instance)->per_stream_cache[transaction->Stream_id]->Evict_one_slot_lru();
							if (evicted_slot.Status == Cache_Slot_Status::DIRTY_NO_FLASH_WRITEBACK) {
								Memory_Transfer_Info* transfer_info = new Memory_Transfer_Info;
								transfer_info->Size_in_bytes = count_sector_no_from_status_bitmap(evicted_slot.State_bitmap_of_existing_sectors) * SECTOR_SIZE_IN_BYTE;
								evicted_cache_slots->push_back(new NVM_Transaction_Flash_WR(Transaction_Source_Type::USERIO,
									transaction->Stream_id, transfer_info->Size_in_bytes, evicted_slot.LPA, NULL, IO_Flow_Priority_Class::UNDEFINED, evicted_slot.Content,
									evicted_slot.State_bitmap_of_existing_sectors, evicted_slot.Timestamp));
								transfer_info->Related_request = evicted_cache_slots;
								transfer_info->next_event_type = Data_Cache_Simulation_Event_Type::MEMORY_READ_FOR_CACHE_EVICTION_FINISHED;
								transfer_info->Stream_id = transaction->Stream_id;
								unsigned int cache_eviction_read_size_in_sectors = count_sector_no_from_status_bitmap(evicted_slot.State_bitmap_of_existing_sectors);
								int sharing_id = transaction->Stream_id;
								if (((Data_Cache_Manager_Flash_Advanced*)_my_instance)->shared_dram_request_queue) {
									sharing_id = 0;
								}
								((Data_Cache_Manager_Flash_Advanced*)_my_instance)->back_pressure_buffer_depth[sharing_id] += cache_eviction_read_size_in_sectors;
								((Data_Cache_Manager_Flash_Advanced*)_my_instance)->service_dram_access_request(transfer_info);
							}
						}
						((Data_Cache_Manager_Flash_Advanced*)_my_instance)->per_stream_cache[transaction->Stream_id]->Insert_read_data(transaction->Stream_id, transaction->LPA,
							((NVM_Transaction_Flash_RD*)transaction)->Content, ((NVM_Transaction_Flash_RD*)transaction)->DataTimeStamp, ((NVM_Transaction_Flash_RD*)transaction)->read_sectors_bitmap);

						Memory_Transfer_Info* transfer_info = new Memory_Transfer_Info;
						transfer_info->Size_in_bytes = count_sector_no_from_status_bitmap(((NVM_Transaction_Flash_RD*)transaction)->read_sectors_bitmap) * SECTOR_SIZE_IN_BYTE;
						transfer_info->next_event_type = Data_Cache_Simulation_Event_Type::MEMORY_WRITE_FOR_CACHE_FINISHED;
						transfer_info->Stream_id = transaction->Stream_id;
						((Data_Cache_Manager_Flash_Advanced*)_my_instance)->service_dram_access_request(transfer_info);
					}

					transaction->UserIORequest->Transaction_list.remove(transaction);
					if (_my_instance->is_user_request_finished(transaction->UserIORequest)) {
						_my_instance->broadcast_user_request_serviced_signal(transaction->UserIORequest);
					}
					break;
				}
			}
		} else {//This is a write request
			switch (Data_Cache_Manager_Flash_Advanced::caching_mode_per_input_stream[transaction->Stream_id])
			{
				case Caching_Mode::TURNED_OFF:
				case Caching_Mode::READ_CACHE:
					transaction->UserIORequest->Transaction_list.remove(transaction);
					if (_my_instance->is_user_request_finished(transaction->UserIORequest)) {
						_my_instance->broadcast_user_request_serviced_signal(transaction->UserIORequest);
					}
					break;
				case Caching_Mode::WRITE_CACHE:
				case Caching_Mode::WRITE_READ_CACHE:
				{
					int sharing_id = transaction->Stream_id;
					if (((Data_Cache_Manager_Flash_Advanced*)_my_instance)->shared_dram_request_queue) {
						sharing_id = 0;
					}
					((Data_Cache_Manager_Flash_Advanced*)_my_instance)->back_pressure_buffer_depth[sharing_id] -= transaction->Data_and_metadata_size_in_byte / SECTOR_SIZE_IN_BYTE + (transaction->Data_and_metadata_size_in_byte % SECTOR_SIZE_IN_BYTE == 0 ? 0 : 1);

					if (((Data_Cache_Manager_Flash_Advanced*)_my_instance)->per_stream_cache[transaction->Stream_id]->Exists(transaction->Stream_id, ((NVM_Transaction_Flash_WR*)transaction)->LPA)) {
						Data_Cache_Slot_Type slot = ((Data_Cache_Manager_Flash_Advanced*)_my_instance)->per_stream_cache[transaction->Stream_id]->Get_slot(transaction->Stream_id, ((NVM_Transaction_Flash_WR*)transaction)->LPA);
						sim_time_type timestamp = slot.Timestamp;
						NVM::memory_content_type content = slot.Content;
						if (((NVM_Transaction_Flash_WR*)transaction)->DataTimeStamp >= timestamp) {
							((Data_Cache_Manager_Flash_Advanced*)_my_instance)->per_stream_cache[transaction->Stream_id]->Remove_slot(transaction->Stream_id, ((NVM_Transaction_Flash_WR*)transaction)->LPA);
						}
					}
					
					auto user_request = ((Data_Cache_Manager_Flash_Advanced*)_my_instance)->waiting_user_requests_queue_for_dram_free_slot[sharing_id].begin();
					while (user_request != ((Data_Cache_Manager_Flash_Advanced*)_my_instance)->waiting_user_requests_queue_for_dram_free_slot[sharing_id].end())
					{
						((Data_Cache_Manager_Flash_Advanced*)_my_instance)->write_to_destage_buffer(*user_request);
						if ((*user_request)->Transaction_list.size() == 0) {
							((Data_Cache_Manager_Flash_Advanced*)_my_instance)->waiting_user_requests_queue_for_dram_free_slot[sharing_id].erase(user_request++);
						} else {
							user_request++;
						}
						//The traffic load on the backend is high and the waiting requests cannot be serviced
						if (((Data_Cache_Manager_Flash_Advanced*)_my_instance)->back_pressure_buffer_depth[sharing_id] > ((Data_Cache_Manager_Flash_Advanced*)_my_instance)->back_pressure_buffer_max_depth) {
							break;
						}
					}

					/*if (_my_instance->back_pressure_buffer_depth[sharing_id] < _my_instance->back_pressure_buffer_max_depth)//The traffic load on the backend is low and the waiting requests can be serviced
					{
						std::list<NVM_Transaction*>* evicted_cache_slots = new std::list<NVM_Transaction*>;
						while (!((Data_Cache_Manager_Flash_Advanced*)_my_instance)->per_stream_cache[transaction->Stream_id]->Empty())
						{
							DataCacheSlotType evicted_slot = ((Data_Cache_Manager_Flash_Advanced*)_my_instance)->per_stream_cache[transaction->Stream_id]->Evict_one_dirty_slot();
							if (evicted_slot.Status != CacheSlotStatus::EMPTY)
							{
								evicted_cache_slots->push_back(new NVM_Transaction_Flash_WR(Transaction_Source_Type::CACHE,
									transaction->Stream_id, count_sector_no_from_status_bitmap(evicted_slot.State_bitmap_of_existing_sectors) * SECTOR_SIZE_IN_BYTE,
									evicted_slot.LPA, NULL, IO_Flow_Priority_Class::UNDEFINED, evicted_slot.Content, evicted_slot.State_bitmap_of_existing_sectors, evicted_slot.Timestamp));
								_my_instance->back_pressure_buffer_depth[sharing_id] += count_sector_no_from_status_bitmap(evicted_slot.State_bitmap_of_existing_sectors);
								cache_eviction_read_size_in_sectors += count_sector_no_from_status_bitmap(evicted_slot.State_bitmap_of_existing_sectors);
							}
							else break;
							if (_my_instance->back_pressure_buffer_depth[sharing_id] >= _my_instance->back_pressure_buffer_max_depth)
								break;
						}
						
						if (cache_eviction_read_size_in_sectors > 0)
						{
							Memory_Transfer_Info* read_transfer_info = new Memory_Transfer_Info;
							read_transfer_info->Size_in_bytes = cache_eviction_read_size_in_sectors * SECTOR_SIZE_IN_BYTE;
							read_transfer_info->Related_request = evicted_cache_slots;
							read_transfer_info->next_event_type = Data_Cache_Simulation_Event_Type::MEMORY_READ_FOR_CACHE_EVICTION_FINISHED;
							read_transfer_info->Stream_id = transaction->Stream_id;
							((Data_Cache_Manager_Flash_Advanced*)_my_instance)->service_dram_access_request(read_transfer_info);
						}
					}*/

					break;
				}
			}
		}
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl 0x4(%rdi), %eax
cmpl $0x1, %eax
ja 0x332b1
movq %rdi, %rbx
testl %eax, %eax
jne 0x32c63
leaq 0x3c9c8(%rip), %rax     # 0x6f620
movq (%rax), %rdi
movq %rbx, %rsi
callq 0x32256
cmpl $0x0, 0x8(%rbx)
je 0x32dbb
leaq 0x3c9b4(%rip), %rax     # 0x6f628
movq (%rax), %rax
movzwl (%rbx), %esi
movl (%rax,%rsi,4), %eax
cmpq $0x3, %rax
ja 0x332b1
leaq 0x2650a(%rip), %rcx     # 0x59198
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0x3c982(%rip), %r15     # 0x6f620
movq (%r15), %rax
movl 0x50(%rbx), %ecx
movl %ecx, %edx
shrl $0x9, %edx
andl $0x1ff, %ecx            # imm = 0x1FF
xorl %r12d, %r12d
cmpb $0x0, 0xe0(%rax)
movq 0xf0(%rax), %rdi
cmoveq %rsi, %r12
movl (%rdi,%r12,4), %r8d
subl %edx, %r8d
cmpl $0x1, %ecx
adcl $-0x1, %r8d
movl %r8d, (%rdi,%r12,4)
movq 0xc0(%rax), %rax
movq (%rax,%rsi,8), %rdi
movq 0x58(%rbx), %rdx
callq 0x31522
testb %al, %al
je 0x32d35
movq (%r15), %rax
movq 0xc0(%rax), %rax
movzwl (%rbx), %edx
movq (%rax,%rdx,8), %rsi
movq 0x58(%rbx), %rcx
movq %rsp, %r14
movq %r14, %rdi
callq 0x3158a
movq 0xa0(%rbx), %rax
cmpq 0x18(%r14), %rax
jb 0x32d35
movq (%r15), %rax
movq 0xc0(%rax), %rax
movzwl (%rbx), %esi
movq (%rax,%rsi,8), %rdi
movq 0x58(%rbx), %rdx
callq 0x31ae6
movq (%r15), %rdi
movq 0xd8(%rdi), %rax
leaq (%r12,%r12,2), %r14
movq (%rax,%r14,8), %rbx
leal (,%r14,8), %r13d
movq 0xd8(%rdi), %rax
addq %r13, %rax
cmpq %rax, %rbx
je 0x332b1
movq 0x10(%rbx), %rsi
callq 0x33988
movq 0x10(%rbx), %rax
cmpq $0x0, 0x50(%rax)
je 0x32d7b
movq (%rbx), %rbx
jmp 0x32da0
movq (%r15), %rax
movq 0xd8(%rax), %rax
movq (%rbx), %rbp
decq 0x10(%rax,%r14,8)
movq %rbx, %rdi
callq 0x7580
movq %rbx, %rdi
callq 0x7370
movq %rbp, %rbx
movq (%r15), %rdi
movq 0xf0(%rdi), %rax
movl (%rax,%r12,4), %eax
cmpl 0xe8(%rdi), %eax
jbe 0x32d4f
jmp 0x332b1
movq 0x88(%rbx), %rax
testq %rax, %rax
je 0x32dd7
movq $0x0, 0x88(%rax)
jmp 0x332b1
leaq 0x3c84a(%rip), %rax     # 0x6f628
movq (%rax), %rax
movzwl (%rbx), %esi
movl (%rax,%rsi,4), %eax
leal -0x1(%rax), %ecx
cmpl $0x2, %ecx
jb 0x32e3c
cmpl $0x3, %eax
je 0x32dfc
testl %eax, %eax
jne 0x332b1
movq 0x10(%rbx), %rdi
addq $0x40, %rdi
movq %rsp, %rsi
movq %rbx, (%rsi)
callq 0x344cc
movq 0x10(%rbx), %rsi
cmpq $0x0, 0x50(%rsi)
jne 0x332b1
cmpl $0x0, 0x58(%rsi)
jne 0x332b1
leaq 0x3c7f1(%rip), %rax     # 0x6f620
movq (%rax), %rdi
callq 0x321ee
jmp 0x332b1
leaq 0x3c7dd(%rip), %r13     # 0x6f620
movq (%r13), %rax
movq 0xc0(%rax), %rax
movq (%rax,%rsi,8), %rdi
movq 0x58(%rbx), %rdx
callq 0x31522
testb %al, %al
je 0x32ea3
movq (%r13), %rax
movq 0xc0(%rax), %rax
movzwl (%rbx), %edx
movq (%rax,%rdx,8), %rsi
movq 0x58(%rbx), %rcx
movq %rsp, %r14
movq %r14, %rdi
callq 0x3158a
movq 0x18(%r14), %r8
movq 0x98(%rbx), %rax
cmpq %r8, %rax
jbe 0x33262
movq 0x80(%rbx), %rcx
movq %rax, %r8
jmp 0x33267
movq (%r13), %rax
movq 0xc0(%rax), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %rdi
callq 0x31624
testb %al, %al
jne 0x33137
movl $0x18, %edi
callq 0x73a0
movq %rax, %r15
movq %rax, 0x8(%rax)
movq %rax, (%rax)
movq $0x0, 0x10(%rax)
movq (%r13), %rax
movq 0xc0(%rax), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %rsi
movq %rsp, %r14
movq %r14, %rdi
callq 0x3172e
cmpl $0x2, 0x20(%r14)
jne 0x33137
movl $0x18, %edi
callq 0x73a0
movq %rax, %r14
movq (%rsp), %rax
movq %rax, 0x38(%rsp)
movq %rax, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
movdqa 0x255c2(%rip), %xmm1    # 0x584f0
movdqa 0x255ca(%rip), %xmm2    # 0x58500
pxor %xmm3, %xmm3
movl $0x40, %eax
movdqa 0x255c8(%rip), %xmm10   # 0x58510
pcmpeqd %xmm4, %xmm4
movdqa 0x255cb(%rip), %xmm11   # 0x58520
pxor %xmm5, %xmm5
movdqa %xmm10, %xmm6
psllq %xmm2, %xmm6
pshufd $0xee, %xmm2, %xmm7     # xmm7 = xmm2[2,3,2,3]
movdqa %xmm10, %xmm8
psllq %xmm7, %xmm8
movsd %xmm6, %xmm8            # xmm8 = xmm6[0],xmm8[1]
movdqa %xmm10, %xmm6
psllq %xmm1, %xmm6
pshufd $0xee, %xmm1, %xmm7     # xmm7 = xmm1[2,3,2,3]
movdqa %xmm10, %xmm9
psllq %xmm7, %xmm9
movsd %xmm6, %xmm9            # xmm9 = xmm6[0],xmm9[1]
andpd %xmm0, %xmm9
andpd %xmm0, %xmm8
pcmpeqd %xmm3, %xmm8
pcmpeqd %xmm3, %xmm9
movdqa %xmm8, %xmm6
shufps $0xdd, %xmm9, %xmm6     # xmm6 = xmm6[1,3],xmm9[1,3]
shufps $0x88, %xmm9, %xmm8     # xmm8 = xmm8[0,2],xmm9[0,2]
andps %xmm6, %xmm8
paddd %xmm8, %xmm5
psubd %xmm4, %xmm5
paddq %xmm11, %xmm2
paddq %xmm11, %xmm1
addq $-0x4, %rax
jne 0x32f59
pshufd $0xee, %xmm5, %xmm0     # xmm0 = xmm5[2,3,2,3]
paddd %xmm5, %xmm0
pshufd $0x55, %xmm0, %xmm1     # xmm1 = xmm0[1,1,1,1]
paddd %xmm0, %xmm1
movd %xmm1, %ebp
shll $0x9, %ebp
movl %ebp, (%r14)
movl $0xb0, %edi
callq 0x73a0
movq %rax, %r12
movzwl (%rbx), %edx
movq 0x8(%rsp), %r8
movq %rax, %rdi
xorl %esi, %esi
movl %ebp, %ecx
xorl %r9d, %r9d
pushq 0x18(%rsp)
pushq 0x40(%rsp)
pushq 0x20(%rsp)
pushq $0x2710                 # imm = 0x2710
callq 0x48218
addq $0x20, %rsp
leaq 0x40(%rsp), %rsi
movq %r12, (%rsi)
movq %r15, %rdi
callq 0x3449a
movq %r15, 0x8(%r14)
movl $0x0, 0x10(%r14)
movzwl (%rbx), %eax
movw %ax, 0x14(%r14)
movdqa 0x2549c(%rip), %xmm0    # 0x584f0
movdqa 0x254a4(%rip), %xmm1    # 0x58500
pxor %xmm2, %xmm2
movl $0x40, %ecx
pshufd $0x44, (%rsp), %xmm3    # xmm3 = mem[0,1,0,1]
pcmpeqd %xmm4, %xmm4
pxor %xmm5, %xmm5
movdqa 0x25494(%rip), %xmm10   # 0x58510
movdqa 0x2549b(%rip), %xmm11   # 0x58520
movdqa %xmm10, %xmm6
psllq %xmm1, %xmm6
pshufd $0xee, %xmm1, %xmm7     # xmm7 = xmm1[2,3,2,3]
movdqa %xmm10, %xmm8
psllq %xmm7, %xmm8
movsd %xmm6, %xmm8            # xmm8 = xmm6[0],xmm8[1]
movdqa %xmm10, %xmm6
psllq %xmm0, %xmm6
pshufd $0xee, %xmm0, %xmm7     # xmm7 = xmm0[2,3,2,3]
movdqa %xmm10, %xmm9
psllq %xmm7, %xmm9
movsd %xmm6, %xmm9            # xmm9 = xmm6[0],xmm9[1]
andpd %xmm3, %xmm9
andpd %xmm3, %xmm8
pcmpeqd %xmm2, %xmm8
pcmpeqd %xmm2, %xmm9
movdqa %xmm8, %xmm6
shufps $0xdd, %xmm9, %xmm6     # xmm6 = xmm6[1,3],xmm9[1,3]
shufps $0x88, %xmm9, %xmm8     # xmm8 = xmm8[0,2],xmm9[0,2]
andps %xmm6, %xmm8
paddd %xmm8, %xmm5
psubd %xmm4, %xmm5
paddq %xmm11, %xmm1
paddq %xmm11, %xmm0
addq $-0x4, %rcx
jne 0x33085
pshufd $0xee, %xmm5, %xmm0     # xmm0 = xmm5[2,3,2,3]
paddd %xmm5, %xmm0
pshufd $0x55, %xmm0, %xmm1     # xmm1 = xmm0[1,1,1,1]
paddd %xmm0, %xmm1
movd %xmm1, %ecx
movq (%r13), %rdi
xorl %edx, %edx
cmpb $0x0, 0xe0(%rdi)
cmovel %eax, %edx
movq 0xf0(%rdi), %rax
addl %ecx, (%rax,%rdx,4)
movq %r14, %rsi
callq 0x336f4
movq (%r13), %rax
movq 0xc0(%rax), %rax
movzwl (%rbx), %esi
movq (%rax,%rsi,8), %rdi
movq 0x58(%rbx), %rdx
movq 0x80(%rbx), %rcx
movq 0x98(%rbx), %r8
movq 0x90(%rbx), %r9
callq 0x317fc
movl $0x18, %edi
callq 0x73a0
movq 0x90(%rbx), %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
movdqa 0x2536a(%rip), %xmm1    # 0x584f0
movdqa 0x25372(%rip), %xmm2    # 0x58500
pxor %xmm3, %xmm3
movl $0x40, %ecx
movdqa 0x25371(%rip), %xmm4    # 0x58510
pcmpeqd %xmm5, %xmm5
movdqa 0x25375(%rip), %xmm6    # 0x58520
pxor %xmm7, %xmm7
movdqa %xmm4, %xmm8
psllq %xmm2, %xmm8
pshufd $0xee, %xmm2, %xmm9     # xmm9 = xmm2[2,3,2,3]
movdqa %xmm4, %xmm10
psllq %xmm9, %xmm10
movsd %xmm8, %xmm10           # xmm10 = xmm8[0],xmm10[1]
movdqa %xmm4, %xmm8
psllq %xmm1, %xmm8
pshufd $0xee, %xmm1, %xmm9     # xmm9 = xmm1[2,3,2,3]
movdqa %xmm4, %xmm11
psllq %xmm9, %xmm11
movsd %xmm8, %xmm11           # xmm11 = xmm8[0],xmm11[1]
andpd %xmm0, %xmm11
andpd %xmm0, %xmm10
pcmpeqd %xmm3, %xmm10
pcmpeqd %xmm3, %xmm11
movdqa %xmm10, %xmm8
shufps $0xdd, %xmm11, %xmm8    # xmm8 = xmm8[1,3],xmm11[1,3]
shufps $0x88, %xmm11, %xmm10   # xmm10 = xmm10[0,2],xmm11[0,2]
andps %xmm8, %xmm10
paddd %xmm10, %xmm7
psubd %xmm5, %xmm7
paddq %xmm6, %xmm2
paddq %xmm6, %xmm1
addq $-0x4, %rcx
jne 0x331af
pshufd $0xee, %xmm7, %xmm0     # xmm0 = xmm7[2,3,2,3]
paddd %xmm7, %xmm0
pshufd $0x55, %xmm0, %xmm1     # xmm1 = xmm0[1,1,1,1]
paddd %xmm0, %xmm1
movd %xmm1, %ecx
shll $0x9, %ecx
movl %ecx, (%rax)
movl $0x1, 0x10(%rax)
movzwl (%rbx), %ecx
movw %cx, 0x14(%rax)
movq (%r13), %rdi
movq %rax, %rsi
callq 0x336f4
jmp 0x3328d
movq 0x10(%rsp), %rcx
movq (%r13), %rax
movq 0xc0(%rax), %rax
movzwl (%rbx), %esi
movq (%rax,%rsi,8), %rdi
movq 0x58(%rbx), %rdx
movq (%rsp), %r9
orq 0x90(%rbx), %r9
callq 0x31a44
movq 0x10(%rbx), %rdi
addq $0x40, %rdi
movq %rsp, %rsi
movq %rbx, (%rsi)
callq 0x344cc
movq 0x10(%rbx), %rsi
cmpq $0x0, 0x50(%rsi)
jne 0x332b1
cmpl $0x0, 0x58(%rsi)
je 0x332c0
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%r13), %rdi
jmp 0x32e32
movq %rax, %rbx
movq %r12, %rdi
callq 0x7370
movq %rbx, %rdi
callq 0x7620