// 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::generate_flash_writeback_request_for_mapping_data(unsigned short, unsigned long)
void Address_Mapping_Unit_Page_Level::generate_flash_writeback_request_for_mapping_data(const stream_id_type stream_id, const LPA_type lpn)
	{
		MVPN_type mvpn = get_MVPN(lpn, stream_id);
		if (is_mvpn_locked_for_gc(stream_id, mvpn)) {
			manage_mapping_transaction_facing_barrier(stream_id, mvpn, false);
			domains[stream_id]->DepartingMappingEntries.insert(get_MVPN(lpn, stream_id));
		} else {
			ftl->TSU->Prepare_for_transaction_submit();

			//Writing back all dirty CMT entries that fall into the same translation virtual page (MVPN)
			unsigned int read_size = 0;
			page_status_type readSectorsBitmap = 0;
			LPA_type startLPN = get_start_LPN_in_MVP(mvpn);
			LPA_type endLPN = get_end_LPN_in_MVP(mvpn);
			for (LPA_type lpn_itr = startLPN; lpn_itr <= endLPN; lpn_itr++) {
				if (domains[stream_id]->CMT->Exists(stream_id, lpn_itr)) {
					if (domains[stream_id]->CMT->Is_dirty(stream_id, lpn_itr)) {
						domains[stream_id]->CMT->Make_clean(stream_id, lpn_itr);
						domains[stream_id]->GlobalMappingTable[lpn_itr].PPA = domains[stream_id]->CMT->Retrieve_ppa(stream_id, lpn_itr);
					} else {
						page_status_type bitlocation = (((page_status_type)0x1) << (((lpn_itr - startLPN) * GTD_entry_size) / SECTOR_SIZE_IN_BYTE));
						if ((readSectorsBitmap & bitlocation) == 0) {
							readSectorsBitmap |= bitlocation;
							read_size += SECTOR_SIZE_IN_BYTE;
						}
					}
				}
			}

			//Read the unchaged mapping entries from flash to merge them with updated parts of MVPN
			NVM_Transaction_Flash_RD* readTR = NULL;
			MPPN_type mppn = domains[stream_id]->GlobalTranslationDirectory[mvpn].MPPN;
			if (mppn != NO_MPPN) {
				readTR = new NVM_Transaction_Flash_RD(Transaction_Source_Type::MAPPING, stream_id, read_size,
					mvpn, mppn, NULL, mvpn, NULL, readSectorsBitmap, CurrentTimeStamp);
				Convert_ppa_to_address(mppn, readTR->Address);
				block_manager->Read_transaction_issued(readTR->Address);//Inform block_manager as soon as the transaction's target address is determined
				domains[stream_id]->ArrivingMappingEntries.insert(std::pair<MVPN_type, LPA_type>(mvpn, lpn));
				ftl->TSU->Submit_transaction(readTR);
			}

			NVM_Transaction_Flash_WR* writeTR = new NVM_Transaction_Flash_WR(Transaction_Source_Type::MAPPING, stream_id, SECTOR_SIZE_IN_BYTE * sector_no_per_page,
				mvpn, mppn, NULL, mvpn, readTR, (((page_status_type)0x1) << sector_no_per_page) - 1, CurrentTimeStamp);
			allocate_plane_for_translation_write(writeTR);
			allocate_page_in_plane_for_translation_write(writeTR, mvpn, false);
			domains[stream_id]->DepartingMappingEntries.insert(get_MVPN(lpn, stream_id));
			ftl->TSU->Submit_transaction(writeTR);

			Stats::Total_flash_reads_for_mapping++;
			Stats::Total_flash_writes_for_mapping++;
			Stats::Total_flash_reads_for_mapping_per_stream[stream_id]++;
			Stats::Total_flash_writes_for_mapping_per_stream[stream_id]++;

			ftl->TSU->Schedule();
		}
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdx, %r15
movl %esi, %ebp
movq %rdi, %rbx
movl 0xc0(%rdi), %ecx
xorl %r13d, %r13d
movq %rdx, %rax
xorl %edx, %edx
divq %rcx
movq %rax, %r12
movq (%rdi), %rax
movl %r12d, %edx
callq *0xf0(%rax)
testb %al, %al
je 0x2e4d7
movq (%rbx), %rax
movzwl %bp, %r14d
movq %rbx, %rdi
movl %r14d, %esi
movl %r12d, %edx
xorl %ecx, %ecx
callq *0xe0(%rax)
movq 0xa8(%rbx), %rax
movl $0xb8, %edi
addq (%rax,%r14,8), %rdi
movl 0xc0(%rbx), %ecx
movq %r15, %rax
xorl %edx, %edx
divq %rcx
leaq 0x28(%rsp), %rsi
movl %eax, (%rsi)
callq 0x31b0e
jmp 0x2e8a4
movq %r15, 0x18(%rsp)
movq 0x30(%rbx), %rax
movq 0x50(%rax), %rdi
callq 0x2fd9e
movl 0xc0(%rbx), %eax
leal 0x1(%r12), %r14d
imull %eax, %r14d
imull %r12d, %eax
decl %r14d
movzwl %bp, %r15d
cmpl %r14d, %eax
movq %r12, 0x10(%rsp)
jbe 0x2e515
xorl %r12d, %r12d
jmp 0x2e687
movq %r15, %rcx
shlq $0x38, %rcx
movq %rcx, (%rsp)
xorl %r13d, %r13d
xorl %r12d, %r12d
movq %rax, 0x20(%rsp)
movq %rax, %rbp
movq %r14, 0x8(%rsp)
movq 0xa8(%rbx), %rax
movq (%rax,%r15,8), %rax
movq 0x10(%rax), %rdi
movq %rbp, %rcx
orq (%rsp), %rcx
movq (%rdi), %r8
movq 0x8(%rdi), %r9
movq %rcx, %rax
xorl %edx, %edx
divq %r9
movq %rdx, %rsi
movq (%r8,%rdx,8), %rdx
movl $0x0, %eax
testq %rdx, %rdx
je 0x2e5a2
movq (%rdx), %r10
movq %rdx, %rax
cmpq 0x8(%r10), %rcx
je 0x2e5a2
movq %r10, %r11
movq (%r10), %r10
testq %r10, %r10
je 0x2e5a0
movq 0x8(%r10), %r8
movq %r8, %rax
xorl %edx, %edx
divq %r9
movl $0x0, %eax
cmpq %rsi, %rdx
jne 0x2e5a2
movq %r11, %rax
cmpq %r8, %rcx
jne 0x2e575
jmp 0x2e5a2
xorl %eax, %eax
testq %rax, %rax
je 0x2e5ac
movq (%rax), %rax
jmp 0x2e5ae
xorl %eax, %eax
testq %rax, %rax
je 0x2e677
movq 0x10(%rax), %rax
cmpl $0x2, 0x14(%rax)
jne 0x2e677
movl %r15d, %esi
movq %rbp, %rdx
callq 0x29bd2
testb %al, %al
je 0x2e641
movq 0xa8(%rbx), %rax
movq %r12, %r14
movq %r13, %r12
leal (,%r15,8), %r13d
movq (%rax,%r13), %rax
movq 0x10(%rax), %rdi
movl %r15d, %esi
movq %rbp, %rdx
callq 0x29c9c
movq 0xa8(%rbx), %rax
movq (%rax,%r13), %rax
movq 0x10(%rax), %rdi
movl %r15d, %esi
movq %rbp, %rdx
callq 0x29600
movq 0xa8(%rbx), %rcx
movq (%rcx,%r13), %rcx
movq %r12, %r13
movq %r14, %r12
movq 0x8(%rsp), %r14
movq 0x20(%rcx), %rcx
leaq (,%rbp,2), %rdx
addq %rbp, %rdx
movq %rax, (%rcx,%rdx,8)
jmp 0x2e677
movl %ebp, %ecx
subl 0x20(%rsp), %ecx
imull 0xb4(%rbx), %ecx
shrl $0x9, %ecx
movl $0x1, %eax
shlq %cl, %rax
leal 0x200(%r13), %edx
btq %rcx, %r12
movl $0x0, %ecx
cmovbq %rcx, %rax
cmovbl %r13d, %edx
orq %rax, %r12
movl %edx, %r13d
leaq 0x1(%rbp), %rax
cmpq %r14, %rbp
movq %rax, %rbp
jb 0x2e533
movq 0xa8(%rbx), %rax
movq (%rax,%r15,8), %rax
movq (%rax), %rax
movl 0x10(%rsp), %r14d
movq %r14, %rcx
shlq $0x4, %rcx
movl (%rax,%rcx), %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rcx, (%rsp)
cmpq %rax, %rcx
je 0x2e784
movl $0xa0, %edi
callq 0x73a0
movq %rax, %rbp
callq 0x281b4
movq %rax, %rdi
callq 0x285a6
subq $0x8, %rsp
xorl %r10d, %r10d
movq %rbp, %rdi
movl $0x3, %esi
movl %r15d, %edx
movl %r13d, %ecx
movq %r14, %r8
movq 0x8(%rsp), %r9
pushq %rax
pushq %r12
pushq %r10
pushq %r14
pushq %r10
callq 0x48a88
addq $0x30, %rsp
movq %rbp, %r13
addq $0x38, %r13
movq (%rbx), %rax
movq %rbx, %rdi
movq (%rsp), %rsi
movq %r13, %rdx
callq *0x88(%rax)
movq 0x40(%rbx), %rdi
movq %r13, %rsi
callq 0x3e230
movq 0xa8(%rbx), %rax
movl $0x88, %edi
addq (%rax,%r15,8), %rdi
leaq 0x28(%rsp), %rsi
movq 0x10(%rsp), %rax
movl %eax, (%rsi)
movq 0x18(%rsp), %rax
movq %rax, 0x8(%rsi)
callq 0x31a40
movq 0x30(%rbx), %rax
movq 0x50(%rax), %r12
leaq 0x78(%r12), %r13
movl $0x18, %edi
callq 0x73a0
movq %rbp, 0x10(%rax)
movq %rax, %rdi
movq %r13, %rsi
callq 0x7060
incq 0x88(%r12)
movq %rbp, 0x8(%rsp)
jmp 0x2e78d
movq $0x0, 0x8(%rsp)
movl $0xb0, %edi
callq 0x73a0
movq %rax, %rbp
movl 0x7c(%rbx), %r13d
movq $-0x1, %r12
movl %r13d, %ecx
shlq %cl, %r12
callq 0x281b4
movq %rax, %rdi
callq 0x285a6
shll $0x9, %r13d
notq %r12
subq $0x8, %rsp
movq %rbp, %rdi
movl $0x3, %esi
movl %r15d, %edx
movl %r13d, %ecx
movq %r14, %r8
movq 0x8(%rsp), %r9
pushq %rax
pushq %r12
pushq 0x20(%rsp)
pushq %r14
pushq $0x0
callq 0x48c24
addq $0x30, %rsp
movq %rbx, %rdi
movq %rbp, %rsi
callq 0x2b926
movq %rbx, %rdi
movq %rbp, %rsi
movq 0x10(%rsp), %rdx
xorl %ecx, %ecx
callq 0x2ad08
movq 0xa8(%rbx), %rax
leal (,%r15,8), %r15d
movl $0xb8, %edi
addq (%rax,%r15), %rdi
movl 0xc0(%rbx), %ecx
movq 0x18(%rsp), %rax
xorl %edx, %edx
divq %rcx
leaq 0x28(%rsp), %rsi
movl %eax, (%rsi)
callq 0x31b0e
movq 0x30(%rbx), %rax
movq 0x50(%rax), %r12
leaq 0x78(%r12), %r14
movl $0x18, %edi
callq 0x73a0
movq %rbp, 0x10(%rax)
movq %rax, %rdi
movq %r14, %rsi
callq 0x7060
incq 0x88(%r12)
leaq 0x40ead(%rip), %rax     # 0x6f720
incq (%rax)
leaq 0x40eab(%rip), %rax     # 0x6f728
incq (%rax)
leaq 0x40ea9(%rip), %rax     # 0x6f730
incq (%rax,%r15)
leaq 0x4169e(%rip), %rax     # 0x6ff30
incq (%rax,%r15)
movq 0x30(%rbx), %rax
movq 0x50(%rax), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x2e8b5
movq %rax, %rbx
movq %rbp, %rdi
callq 0x7370
movq %rbx, %rdi
callq 0x7620