// File: CMU-SAFARI[P]MQSim/src/ssd/Address_Mapping_Unit_Page_Level.cpp
// Function: SSD_Components::Address_Mapping_Unit_Page_Level::allocate_page_in_plane_for_translation_write(SSD_Components::NVM_Transaction_Flash*, unsigned int, bool)
void Address_Mapping_Unit_Page_Level::allocate_page_in_plane_for_translation_write(NVM_Transaction_Flash* transaction, MVPN_type mvpn, bool is_for_gc)
	{
		AddressMappingDomain* domain = domains[transaction->Stream_id];

		MPPN_type old_MPPN = domain->GlobalTranslationDirectory[mvpn].MPPN;
		/*this is the first access to the mvpn*/
		if (old_MPPN == NO_MPPN) {
			if (is_for_gc) {
				PRINT_ERROR("Unexpected mapping table status in allocate_page_in_plane_for_translation_write for a GC/WL write!")
			}
		} else {
			NVM::FlashMemory::Physical_Page_Address prevAddr;
			Convert_ppa_to_address(old_MPPN, prevAddr);
			block_manager->Invalidate_page_in_block(transaction->Stream_id, prevAddr);
		}

		block_manager->Allocate_block_and_page_in_plane_for_translation_write(transaction->Stream_id, transaction->Address, false);
		transaction->PPA = Convert_address_to_ppa(transaction->Address);
		domain->GlobalTranslationDirectory[mvpn].MPPN = (MPPN_type)transaction->PPA;
		domain->GlobalTranslationDirectory[mvpn].TimeStamp = CurrentTimeStamp;
	}

// Assembly:
subq $0x58, %rsp
movb %cl, %al
movq %rdi, 0x50(%rsp)
movq %rsi, 0x48(%rsp)
movl %edx, 0x44(%rsp)
andb $0x1, %al
movb %al, 0x43(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0xa8(%rax), %rax
movq 0x48(%rsp), %rcx
movzwl (%rcx), %ecx
movq (%rax,%rcx,8), %rax
movq %rax, 0x38(%rsp)
movq 0x38(%rsp), %rax
movq (%rax), %rax
movl 0x44(%rsp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl %eax, 0x34(%rsp)
movl 0x34(%rsp), %eax
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
cmpq %rcx, %rax
jne 0x4cd27
testb $0x1, 0x43(%rsp)
je 0x4cd25
movq 0x8d30f(%rip), %rdi     # 0xd9ff0
leaq 0x5dc00(%rip), %rsi     # 0xaa8e8
callq 0x8440
movq 0x8d2fc(%rip), %rdi     # 0xd9ff0
leaq 0x5fed0(%rip), %rsi     # 0xacbcb
callq 0x8440
movq %rax, %rdi
movq 0x8d24e(%rip), %rsi     # 0xd9f58
callq 0x8480
movq 0x8d2ba(%rip), %rdi     # 0xd9fd0
callq 0x84f0
movl $0x1, %edi
callq 0x8500
jmp 0x4cd7f
leaq 0x1c(%rsp), %rdi
xorl %r9d, %r9d
movl %r9d, %esi
movl %r9d, %edx
movl %r9d, %ecx
movl %r9d, %r8d
movl $0x0, (%rsp)
callq 0x4a220
movq 0x10(%rsp), %rdi
movl 0x34(%rsp), %eax
movl %eax, %esi
movq (%rdi), %rax
leaq 0x1c(%rsp), %rdx
callq *0x88(%rax)
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
movq 0x48(%rsp), %rax
movw (%rax), %cx
movq (%rdi), %rax
leaq 0x1c(%rsp), %rdx
movzwl %cx, %esi
callq *0x30(%rax)
movq 0x10(%rsp), %rax
movq 0x40(%rax), %rdi
movq 0x48(%rsp), %rax
movw (%rax), %si
movq 0x48(%rsp), %rdx
addq $0x38, %rdx
movq (%rdi), %rax
xorl %ecx, %ecx
movzwl %si, %esi
callq *0x20(%rax)
movq 0x10(%rsp), %rdi
movq 0x48(%rsp), %rsi
addq $0x38, %rsi
movq (%rdi), %rax
callq *0x90(%rax)
movq %rax, %rcx
movq 0x48(%rsp), %rax
movq %rcx, 0x60(%rax)
movq 0x48(%rsp), %rax
movq 0x60(%rax), %rax
movl %eax, %ecx
movq 0x38(%rsp), %rax
movq (%rax), %rax
movl 0x44(%rsp), %edx
shlq $0x4, %rdx
addq %rdx, %rax
movl %ecx, (%rax)
callq 0x46500
movq %rax, %rdi
callq 0x46c50
movq %rax, %rcx
movq 0x38(%rsp), %rax
movq (%rax), %rax
movl 0x44(%rsp), %edx
shlq $0x4, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
addq $0x58, %rsp
retq
nopw %cs:(%rax,%rax)