// File: /workspace/github_cpp_makefile_star2_O3/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 $0x28, %rsp
cmpl $0x3, 0x4(%rdi)
jne 0x2f70e
movq 0x403b5(%rip), %rax     # 0x6f608
cmpb $0x1, 0x4c(%rax)
je 0x2f71d
movq %rdi, %rbx
cmpl $0x1, 0x8(%rdi)
jne 0x2f29f
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movl $0xb8, %r14d
addq (%rax,%rcx,8), %r14
movl 0x80(%rbx), %eax
leaq 0x8(%rsp), %rsi
movl %eax, (%rsi)
movq %r14, %rdi
callq 0x305dc
movq %r14, %rdi
movq %rax, %rsi
callq 0x3065a
jmp 0x2f70e
movq 0x88(%rbx), %rcx
testq %rcx, %rcx
je 0x2f2b6
movq $0x0, 0x88(%rcx)
movq 0x30(%rax), %rax
movq 0x50(%rax), %rdi
callq 0x2f762
movq 0x4033e(%rip), %rax     # 0x6f608
movq 0xa8(%rax), %rdx
movzwl (%rbx), %ecx
movq (%rdx,%rcx,8), %rdx
movq 0x98(%rdx), %rsi
testq %rsi, %rsi
je 0x2f700
movl 0x80(%rbx), %r9d
leaq 0x90(%rdx), %rdi
movq %rdi, %r14
xorl %r8d, %r8d
cmpl %r9d, 0x20(%rsi)
setb %r8b
cmovaeq %rsi, %r14
movq 0x10(%rsi,%r8,8), %rsi
testq %rsi, %rsi
jne 0x2f2f9
cmpq %rdi, %r14
je 0x2f700
cmpl %r9d, 0x20(%r14)
ja 0x2f700
cmpl %r9d, 0x20(%r14)
jne 0x2f700
movq %rbx, 0x18(%rsp)
movl %r9d, 0x14(%rsp)
movq 0x28(%r14), %r12
movq 0x10(%rdx), %rdi
movzwl %cx, %esi
movq %r12, %rdx
callq 0x295e0
movq 0x402b5(%rip), %rdi     # 0x6f608
movzwl (%rbx), %ecx
testb %al, %al
je 0x2f6a1
movzwl %cx, %esi
movq 0xa8(%rdi), %rax
movq (%rax,%rsi,8), %rax
movq 0x10(%rax), %rdi
movq 0x20(%rax), %rax
leaq (%r12,%r12,2), %rdx
movq (%rax,%rdx,8), %rcx
movq 0x8(%rax,%rdx,8), %r8
movq %r12, %rdx
callq 0x29548
movq 0x40278(%rip), %rdi     # 0x6f608
movq 0xa8(%rdi), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %r13
movq 0x38(%r13), %rax
testq %rax, %rax
je 0x2f4f7
leaq 0x30(%r13), %rdx
movq %rdx, %rbp
xorl %esi, %esi
cmpq %r12, 0x20(%rax)
setb %sil
cmovaeq %rax, %rbp
movq 0x10(%rax,%rsi,8), %rax
testq %rax, %rax
jne 0x2f3b2
cmpq %rdx, %rbp
je 0x2f4f7
cmpq 0x20(%rbp), %r12
jb 0x2f4f7
cmpq %r12, 0x20(%rbp)
jne 0x2f4f7
movq (%rdi), %rax
movzwl %cx, %esi
movq %r12, %rdx
callq *0xe8(%rax)
movq 0x4020b(%rip), %rdi     # 0x6f608
testb %al, %al
je 0x2f413
movq 0x28(%rbp), %rsi
movq (%rdi), %rax
callq *0xd8(%rax)
jmp 0x2f49d
movzwl (%rbx), %esi
movq 0x28(%rbp), %rdx
callq 0x2ae60
movq 0x401e2(%rip), %rcx     # 0x6f608
testb %al, %al
je 0x2f463
movq 0x30(%rcx), %rax
movq 0x50(%rax), %r13
movq 0x28(%rbp), %r15
leaq 0x78(%r13), %rax
movq %rax, 0x20(%rsp)
movl $0x18, %edi
callq 0x73a0
movq %r15, 0x10(%rax)
movq %rax, %rdi
movq 0x20(%rsp), %rsi
callq 0x7060
incq 0x88(%r13)
jmp 0x2f49d
movq 0x28(%rbp), %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, 0x8(%rsp)
leaq 0x8(%rsp), %rsi
callq 0x3139c
movq 0x40164(%rip), %rax     # 0x6f608
movq 0xa8(%rax), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %r13
addq $0x28, %r13
movq %rbp, %rdi
callq 0x72a0
movq %rax, %r15
movq %r13, %rdi
movq %rbp, %rsi
callq 0x30d8a
movq 0x40135(%rip), %rdi     # 0x6f608
movq 0xa8(%rdi), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %r13
leaq 0x30(%r13), %rax
cmpq %rax, %r15
je 0x2f4f7
movq %r15, %rbp
cmpq %r12, 0x20(%r15)
je 0x2f3e7
movq 0x68(%r13), %rax
addq $0x60, %r13
testq %rax, %rax
je 0x2f52c
movq %r13, %rdx
xorl %esi, %esi
cmpq %r12, 0x20(%rax)
setb %sil
cmovaeq %rax, %rdx
movq 0x10(%rax,%rsi,8), %rax
testq %rax, %rax
jne 0x2f507
cmpq %r13, %rdx
je 0x2f52c
cmpq 0x20(%rdx), %r12
cmovaeq %rdx, %r13
movq 0xa8(%rdi), %rax
movzwl %cx, %edx
movq (%rax,%rdx,8), %rax
addq $0x60, %rax
cmpq %rax, %r13
je 0x2f6a1
cmpq %r12, 0x20(%r13)
jne 0x2f6a1
movq (%rdi), %rax
movzwl %cx, %esi
movq %r12, %rdx
callq *0xe8(%rax)
movq 0x400a1(%rip), %rdi     # 0x6f608
testb %al, %al
je 0x2f57d
movq 0x28(%r13), %rsi
movq (%rdi), %rax
callq *0xd8(%rax)
jmp 0x2f64d
movzwl (%rbx), %esi
movq 0x28(%r13), %rdx
callq 0x2ae60
movq 0x40078(%rip), %rcx     # 0x6f608
testb %al, %al
je 0x2f613
movq 0x30(%rcx), %rax
movq 0x50(%rax), %rbp
movq 0x28(%r13), %rbx
leaq 0x78(%rbp), %r15
movl $0x18, %edi
callq 0x73a0
movq %rbx, 0x10(%rax)
movq 0x18(%rsp), %rbx
movq %rax, %rdi
movq %r15, %rsi
callq 0x7060
incq 0x88(%rbp)
movq 0x28(%r13), %rax
movq 0x88(%rax), %rbp
testq %rbp, %rbp
je 0x2f64d
movq 0x40028(%rip), %rax     # 0x6f608
movq 0x30(%rax), %rax
movq 0x50(%rax), %rbx
leaq 0x78(%rbx), %r15
movl $0x18, %edi
callq 0x73a0
movq %rbp, 0x10(%rax)
movq %rax, %rdi
movq %r15, %rsi
callq 0x7060
incq 0x88(%rbx)
movq 0x18(%rsp), %rbx
jmp 0x2f64d
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, 0x8(%rsp)
leaq 0x8(%rsp), %rsi
callq 0x3139c
movq 0x3ffb4(%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 0x30d8a
movq 0x3ff85(%rip), %rdi     # 0x6f608
movq 0xa8(%rdi), %rax
movzwl (%rbx), %ecx
movq (%rax,%rcx,8), %rax
addq $0x60, %rax
movq %rbp, %r13
cmpq %rax, %rbp
jne 0x2f547
movq 0xa8(%rdi), %rax
movzwl %cx, %ecx
movq (%rax,%rcx,8), %r12
movl $0x88, %eax
addq %rax, %r12
movq %r14, %rdi
callq 0x72a0
movq %rax, %r15
movq %r12, %rdi
movq %r14, %rsi
callq 0x306fa
movq 0x3ff34(%rip), %rax     # 0x6f608
movq 0xa8(%rax), %rdx
movzwl (%rbx), %ecx
movq (%rdx,%rcx,8), %rdx
leaq 0x90(%rdx), %rsi
cmpq %rsi, %r15
je 0x2f700
movq %r15, %r14
movl 0x14(%rsp), %r9d
cmpl %r9d, 0x20(%r15)
je 0x2f339
movq 0x30(%rax), %rax
movq 0x50(%rax), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x10, %edi
callq 0x71d0
movq %rax, %rbx
leaq 0x29553(%rip), %rsi     # 0x58c84
movq %rax, %rdi
callq 0x7500
movq 0x3f880(%rip), %rsi     # 0x6efc0
movq 0x3f839(%rip), %rdx     # 0x6ef80
movq %rbx, %rdi
callq 0x75e0
movq %rax, %r14
movq %rbx, %rdi
callq 0x72c0
movq %r14, %rdi
callq 0x7620