// File: /workspace/github_cpp_makefile_star2_O1/CMU-SAFARI[P]MQSim/src/ssd/Address_Mapping_Unit_Page_Level.cpp
// Function: SSD_Components::Address_Mapping_Unit_Page_Level::handle_transaction_serviced_signal_from_PHY(SSD_Components::NVM_Transaction_Flash*)
inline void Address_Mapping_Unit_Page_Level::handle_transaction_serviced_signal_from_PHY(NVM_Transaction_Flash* transaction)
	{
		//First check if the transaction source is Mapping Module
		if (transaction->Source != Transaction_Source_Type::MAPPING) {
			return;
		}

		if (_my_instance->ideal_mapping_table){
			throw std::logic_error("There should not be any flash read/write when ideal mapping is enabled!");
		}

		if (transaction->Type == Transaction_Type::WRITE) {
			_my_instance->domains[transaction->Stream_id]->DepartingMappingEntries.erase((MVPN_type)((NVM_Transaction_Flash_WR*)transaction)->Content);
		} else {
			/*If this is a read for an MVP that is required for merging unchanged mapping enries
			* (stored on flash) with those updated entries that are evicted from CMT*/
			if (((NVM_Transaction_Flash_RD*)transaction)->RelatedWrite != NULL) {
				((NVM_Transaction_Flash_RD*)transaction)->RelatedWrite->RelatedRead = NULL;
			}

			_my_instance->ftl->TSU->Prepare_for_transaction_submit();
			MVPN_type mvpn = (MVPN_type)((NVM_Transaction_Flash_RD*)transaction)->Content;
			std::multimap<MVPN_type, LPA_type>::iterator it = _my_instance->domains[transaction->Stream_id]->ArrivingMappingEntries.find(mvpn);
			while (it != _my_instance->domains[transaction->Stream_id]->ArrivingMappingEntries.end()) {
				if ((*it).first == mvpn) {
					LPA_type lpa = (*it).second;

					//This mapping entry may arrived due to an update read request that is required for merging new and old mapping entries.
					//If that is the case, we should not insert it into CMT
					if (_my_instance->domains[transaction->Stream_id]->CMT->Is_slot_reserved_for_lpn_and_waiting(transaction->Stream_id, lpa)) {
						_my_instance->domains[transaction->Stream_id]->CMT->Insert_new_mapping_info(transaction->Stream_id, lpa,
							_my_instance->domains[transaction->Stream_id]->GlobalMappingTable[lpa].PPA,
							_my_instance->domains[transaction->Stream_id]->GlobalMappingTable[lpa].WrittenStateBitmap);
						auto it2 = _my_instance->domains[transaction->Stream_id]->Waiting_unmapped_read_transactions.find(lpa);
						while (it2 != _my_instance->domains[transaction->Stream_id]->Waiting_unmapped_read_transactions.end() &&
							(*it2).first == lpa) {
							if (_my_instance->is_lpa_locked_for_gc(transaction->Stream_id, lpa)) {
								_my_instance->manage_user_transaction_facing_barrier(it2->second);
							} else {
								if (_my_instance->translate_lpa_to_ppa(transaction->Stream_id, it2->second)) {
									_my_instance->ftl->TSU->Submit_transaction(it2->second);
								}
								else {
									_my_instance->mange_unsuccessful_translation(it2->second);
								}
							}
							_my_instance->domains[transaction->Stream_id]->Waiting_unmapped_read_transactions.erase(it2++);
						}
						it2 = _my_instance->domains[transaction->Stream_id]->Waiting_unmapped_program_transactions.find(lpa);
						while (it2 != _my_instance->domains[transaction->Stream_id]->Waiting_unmapped_program_transactions.end() &&
							(*it2).first == lpa) {
							if (_my_instance->is_lpa_locked_for_gc(transaction->Stream_id, lpa)) {
								_my_instance->manage_user_transaction_facing_barrier(it2->second);
							} else {
								if (_my_instance->translate_lpa_to_ppa(transaction->Stream_id, it2->second)) {
									_my_instance->ftl->TSU->Submit_transaction(it2->second);
									if (((NVM_Transaction_Flash_WR*)it2->second)->RelatedRead != NULL) {
										_my_instance->ftl->TSU->Submit_transaction(((NVM_Transaction_Flash_WR*)it2->second)->RelatedRead);
									}
								} else {
									_my_instance->mange_unsuccessful_translation(it2->second);
								}
							}
							_my_instance->domains[transaction->Stream_id]->Waiting_unmapped_program_transactions.erase(it2++);
						}
					}
				} else {
					break;
				}
				_my_instance->domains[transaction->Stream_id]->ArrivingMappingEntries.erase(it++);
			}
			_my_instance->ftl->TSU->Schedule();
		}
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
cmpl $0x3, 0x4(%rdi)
jne 0x2fd4a
movq 0x3fd93(%rip), %rax     # 0x6f608
cmpb $0x1, 0x4c(%rax)
je 0x2fd59
movq %rdi, %rbx
cmpl $0x1, 0x8(%rdi)
jne 0x2f8bf
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movl $0xb8, %r14d
addq (%rax,%rcx,8), %r14
movl 0x80(%rbx), %eax
movq %rsp, %rsi
movl %eax, (%rsi)
movq %r14, %rdi
callq 0x30e00
movq %r14, %rdi
movq %rax, %rsi
callq 0x30e78
jmp 0x2fd4a
movq 0x88(%rbx), %rcx
testq %rcx, %rcx
je 0x2f8d6
movq $0x0, 0x88(%rcx)
movq 0x30(%rax), %rax
movq 0x50(%rax), %rdi
callq 0x2fd9e
movl 0x80(%rbx), %esi
movq 0x3fd18(%rip), %rax     # 0x6f608
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %rdi
movq 0x98(%rdi), %rcx
addq $0x90, %rdi
movq %rdi, %rax
testq %rcx, %rcx
je 0x2f92d
movq %rdi, %rax
xorl %edx, %edx
cmpl %esi, 0x20(%rcx)
setb %dl
cmovaeq %rcx, %rax
movq 0x10(%rcx,%rdx,8), %rcx
testq %rcx, %rcx
jne 0x2f917
cmpq %rdi, %rax
je 0x2f939
cmpl %esi, 0x20(%rax)
cmovbeq %rax, %rdi
movq 0x3fcc8(%rip), %rcx     # 0x6f608
movq 0xa8(%rcx), %rdx
movzwl (%rbx), %eax
movq (%rdx,%rax,8), %r13
leaq 0x90(%r13), %rdx
cmpq %rdx, %rdi
je 0x2fd3c
cmpl %esi, 0x20(%rdi)
jne 0x2fd3c
movl %esi, 0xc(%rsp)
movq %rdi, 0x10(%rsp)
movq 0x28(%rdi), %r12
movq 0x10(%r13), %r15
movzwl %ax, %ebp
movq %r15, %rdi
movl %ebp, %esi
movq %r12, %rdx
callq 0x2994c
testb %al, %al
je 0x2fcd2
movq 0x20(%r13), %rax
leaq (%r12,%r12,2), %rdx
movq (%rax,%rdx,8), %rcx
movq 0x8(%rax,%rdx,8), %r8
movq %r15, %rdi
movl %ebp, %esi
movq %r12, %rdx
callq 0x2986e
movq 0x3fc53(%rip), %rax     # 0x6f608
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %r15
movq 0x38(%r15), %rcx
addq $0x30, %r15
movq %r15, %rax
testq %rcx, %rcx
je 0x2f9ed
movq %r15, %rax
xorl %edx, %edx
cmpq %r12, 0x20(%rcx)
setb %dl
cmovaeq %rcx, %rax
movq 0x10(%rcx,%rdx,8), %rcx
testq %rcx, %rcx
jne 0x2f9d6
cmpq %r15, %rax
je 0x2f9fa
cmpq 0x20(%rax), %r12
cmovaeq %rax, %r15
movq 0x3fc07(%rip), %rdi     # 0x6f608
movq 0xa8(%rdi), %rcx
movzwl (%rbx), %eax
movq (%rcx,%rax,8), %r13
leaq 0x30(%r13), %rcx
cmpq %rcx, %r15
je 0x2fb2c
cmpq %r12, 0x20(%r15)
jne 0x2fb2c
movq (%rdi), %rcx
movzwl %ax, %esi
movq %r12, %rdx
callq *0xe8(%rcx)
movq 0x3fbcc(%rip), %rdi     # 0x6f608
testb %al, %al
je 0x2fa52
movq 0x28(%r15), %rsi
movq (%rdi), %rax
callq *0xd8(%rax)
jmp 0x2fad2
movzwl (%rbx), %esi
movq 0x28(%r15), %rdx
callq 0x2b3b8
movq 0x3fba3(%rip), %rcx     # 0x6f608
testb %al, %al
je 0x2fa9b
movq 0x30(%rcx), %rax
movq 0x50(%rax), %rbp
movq 0x28(%r15), %r14
leaq 0x78(%rbp), %r13
movl $0x18, %edi
callq 0x73a0
movq %r14, 0x10(%rax)
movq %rax, %rdi
movq %r13, %rsi
callq 0x7060
incq 0x88(%rbp)
jmp 0x2fad2
movq 0x28(%r15), %rax
movq 0xb8(%rcx), %rcx
movl 0x38(%rax), %edx
movl 0x3c(%rax), %esi
movq (%rcx,%rdx,8), %rcx
movq (%rcx,%rsi,8), %rcx
movl 0x40(%rax), %edx
movl 0x44(%rax), %esi
leaq (%rsi,%rsi,2), %rdi
shlq $0x4, %rdi
addq (%rcx,%rdx,8), %rdi
movq %rax, (%rsp)
movq %rsp, %rsi
callq 0x31bb8
movq 0x3fb2f(%rip), %rax     # 0x6f608
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %r13
addq $0x28, %r13
movq %r15, %rdi
callq 0x72a0
movq %rax, %rbp
movq %r13, %rdi
movq %r15, %rsi
callq 0x315aa
movq 0x3fb00(%rip), %rdi     # 0x6f608
movq 0xa8(%rdi), %rcx
movzwl (%rbx), %eax
movq (%rcx,%rax,8), %r13
leaq 0x30(%r13), %rcx
cmpq %rcx, %rbp
je 0x2fb2c
movq %rbp, %r15
cmpq %r12, 0x20(%rbp)
je 0x2fa26
movq 0x68(%r13), %rcx
addq $0x60, %r13
movq %r13, %rax
testq %rcx, %rcx
je 0x2fb56
movq %r13, %rax
xorl %edx, %edx
cmpq %r12, 0x20(%rcx)
setb %dl
cmovaeq %rcx, %rax
movq 0x10(%rcx,%rdx,8), %rcx
testq %rcx, %rcx
jne 0x2fb3f
cmpq %r13, %rax
je 0x2fb63
cmpq 0x20(%rax), %r12
cmovaeq %rax, %r13
movq 0x3fa9e(%rip), %rdi     # 0x6f608
movq 0xa8(%rdi), %rcx
movzwl (%rbx), %eax
movq (%rcx,%rax,8), %rcx
addq $0x60, %rcx
cmpq %rcx, %r13
je 0x2fcd2
cmpq %r12, 0x20(%r13)
jne 0x2fcd2
movq (%rdi), %rcx
movzwl %ax, %esi
movq %r12, %rdx
callq *0xe8(%rcx)
movq 0x3fa63(%rip), %rdi     # 0x6f608
testb %al, %al
je 0x2fbbb
movq 0x28(%r13), %rsi
movq (%rdi), %rax
callq *0xd8(%rax)
jmp 0x2fc7e
movzwl (%rbx), %esi
movq 0x28(%r13), %rdx
callq 0x2b3b8
movq 0x3fa3a(%rip), %rcx     # 0x6f608
testb %al, %al
je 0x2fc47
movq 0x30(%rcx), %rax
movq 0x50(%rax), %r14
movq 0x28(%r13), %rbp
leaq 0x78(%r14), %r15
movl $0x18, %edi
callq 0x73a0
movq %rbp, 0x10(%rax)
movq %rax, %rdi
movq %r15, %rsi
callq 0x7060
incq 0x88(%r14)
movq 0x28(%r13), %rax
movq 0x88(%rax), %rbp
testq %rbp, %rbp
je 0x2fc7e
movq 0x3f9ef(%rip), %rax     # 0x6f608
movq 0x30(%rax), %rax
movq 0x50(%rax), %r14
leaq 0x78(%r14), %r15
movl $0x18, %edi
callq 0x73a0
movq %rbp, 0x10(%rax)
movq %rax, %rdi
movq %r15, %rsi
callq 0x7060
incq 0x88(%r14)
jmp 0x2fc7e
movq 0x28(%r13), %rax
movq 0xb8(%rcx), %rcx
movl 0x38(%rax), %edx
movl 0x3c(%rax), %esi
movq (%rcx,%rdx,8), %rcx
movq (%rcx,%rsi,8), %rcx
movl 0x40(%rax), %edx
movl 0x44(%rax), %esi
leaq (%rsi,%rsi,2), %rdi
shlq $0x4, %rdi
addq (%rcx,%rdx,8), %rdi
movq %rax, (%rsp)
movq %rsp, %rsi
callq 0x31bb8
movq 0x3f983(%rip), %rax     # 0x6f608
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %r15
addq $0x58, %r15
movq %r13, %rdi
callq 0x72a0
movq %rax, %rbp
movq %r15, %rdi
movq %r13, %rsi
callq 0x315aa
movq 0x3f954(%rip), %rdi     # 0x6f608
movq 0xa8(%rdi), %rcx
movzwl (%rbx), %eax
movq (%rcx,%rax,8), %rcx
addq $0x60, %rcx
movq %rbp, %r13
cmpq %rcx, %rbp
jne 0x2fb85
movq 0x3f92f(%rip), %rax     # 0x6f608
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %r12
movl $0x88, %eax
addq %rax, %r12
movq 0x10(%rsp), %r14
movq %r14, %rdi
callq 0x72a0
movq %rax, %r15
movq %r12, %rdi
movq %r14, %rsi
callq 0x30f18
movq 0x3f8f7(%rip), %rcx     # 0x6f608
movq 0xa8(%rcx), %rdx
movzwl (%rbx), %eax
movq (%rdx,%rax,8), %r13
leaq 0x90(%r13), %rdx
cmpq %rdx, %r15
je 0x2fd3c
movq %r15, %rdi
movl 0xc(%rsp), %esi
cmpl %esi, 0x20(%r15)
je 0x2f96b
movq 0x30(%rcx), %rax
movq 0x50(%rax), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x10, %edi
callq 0x71d0
movq %rax, %rbx
leaq 0x28f17(%rip), %rsi     # 0x58c84
movq %rax, %rdi
callq 0x7500
movq 0x3f244(%rip), %rsi     # 0x6efc0
movq 0x3f205(%rip), %rdx     # 0x6ef88
movq %rbx, %rdi
callq 0x75e0
movq %rax, %r14
movq %rbx, %rdi
callq 0x72c0
movq %r14, %rdi
callq 0x7620