// File: CMU-SAFARI[P]MQSim/src/ssd/Address_Mapping_Unit_Page_Level.cpp
// Function: SSD_Components::Address_Mapping_Unit_Page_Level::Translate_lpa_to_ppa_and_dispatch(std::__cxx11::list<SSD_Components::NVM_Transaction*, std::allocator<SSD_Components::NVM_Transaction*>> const&)
void Address_Mapping_Unit_Page_Level::Translate_lpa_to_ppa_and_dispatch(const std::list<NVM_Transaction*>& transactionList)
	{
		for (std::list<NVM_Transaction*>::const_iterator it = transactionList.begin();
			it != transactionList.end(); ) {
			if (is_lpa_locked_for_gc((*it)->Stream_id, ((NVM_Transaction_Flash*)(*it))->LPA)) {
				//iterator should be post-incremented since the iterator may be deleted from list
				manage_user_transaction_facing_barrier((NVM_Transaction_Flash*)*(it++));
			} else {
				query_cmt((NVM_Transaction_Flash*)(*it++));
			}
		}

		if (transactionList.size() > 0) {
			ftl->TSU->Prepare_for_transaction_submit();
			for (std::list<NVM_Transaction*>::const_iterator it = transactionList.begin();
				it != transactionList.end(); it++) {
				if (((NVM_Transaction_Flash*)(*it))->Physical_address_determined) {
					ftl->TSU->Submit_transaction(static_cast<NVM_Transaction_Flash*>(*it));
					if (((NVM_Transaction_Flash*)(*it))->Type == Transaction_Type::WRITE) {
						if (((NVM_Transaction_Flash_WR*)(*it))->RelatedRead != NULL) {
							ftl->TSU->Submit_transaction(((NVM_Transaction_Flash_WR*)(*it))->RelatedRead);
						}
					}
				}
			}
			
			ftl->TSU->Schedule();
		}
	}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x58(%rsp), %rdi
callq 0x59830
movq %rax, 0x50(%rsp)
movq 0x58(%rsp), %rdi
callq 0x59880
movq %rax, 0x48(%rsp)
leaq 0x50(%rsp), %rdi
leaq 0x48(%rsp), %rsi
callq 0x59860
testb $0x1, %al
jne 0x4d15e
jmp 0x4d1ff
leaq 0x50(%rsp), %rdi
callq 0x598b0
movq (%rax), %rax
movw (%rax), %ax
movw %ax, 0x16(%rsp)
leaq 0x50(%rsp), %rdi
callq 0x598b0
movq 0x18(%rsp), %rdi
movw 0x16(%rsp), %cx
movq (%rax), %rax
movq 0x58(%rax), %rdx
movq (%rdi), %rax
movzwl %cx, %esi
callq *0xe8(%rax)
testb $0x1, %al
jne 0x4d1a0
jmp 0x4d1ce
leaq 0x50(%rsp), %rdi
xorl %esi, %esi
callq 0x598e0
movq %rax, 0x40(%rsp)
leaq 0x40(%rsp), %rdi
callq 0x598b0
movq 0x18(%rsp), %rdi
movq (%rax), %rsi
movq (%rdi), %rax
callq *0xd8(%rax)
jmp 0x4d1fa
leaq 0x50(%rsp), %rdi
xorl %esi, %esi
callq 0x598e0
movq %rax, 0x38(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x598b0
movq 0x18(%rsp), %rdi
movq (%rax), %rsi
movq (%rdi), %rax
callq *0xc8(%rax)
jmp 0x4d137
movq 0x58(%rsp), %rdi
callq 0x59910
cmpq $0x0, %rax
jbe 0x4d322
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x50(%rax), %rdi
callq 0x59940
movq 0x58(%rsp), %rdi
callq 0x59830
movq %rax, 0x30(%rsp)
movq 0x58(%rsp), %rdi
callq 0x59880
movq %rax, 0x28(%rsp)
leaq 0x30(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x59860
testb $0x1, %al
jne 0x4d25b
jmp 0x4d30f
leaq 0x30(%rsp), %rdi
callq 0x598b0
movq (%rax), %rax
testb $0x1, 0x69(%rax)
je 0x4d2f7
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x50(%rax), %rax
movq %rax, 0x8(%rsp)
leaq 0x30(%rsp), %rdi
callq 0x598b0
movq 0x8(%rsp), %rdi
movq (%rax), %rsi
callq 0x59980
leaq 0x30(%rsp), %rdi
callq 0x598b0
movq (%rax), %rax
cmpl $0x1, 0x8(%rax)
jne 0x4d2f5
leaq 0x30(%rsp), %rdi
callq 0x598b0
movq (%rax), %rax
cmpq $0x0, 0x88(%rax)
je 0x4d2f3
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x50(%rax), %rax
movq %rax, (%rsp)
leaq 0x30(%rsp), %rdi
callq 0x598b0
movq (%rsp), %rdi
movq (%rax), %rax
movq 0x88(%rax), %rsi
callq 0x59980
jmp 0x4d2f5
jmp 0x4d2f7
jmp 0x4d2f9
leaq 0x30(%rsp), %rdi
xorl %esi, %esi
callq 0x598e0
movq %rax, 0x20(%rsp)
jmp 0x4d234
movq 0x18(%rsp), %rax
movq 0x30(%rax), %rax
movq 0x50(%rax), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
addq $0x68, %rsp
retq
nopw (%rax,%rax)