// File: /workspace/github_cpp_makefile_star2_O2/CMU-SAFARI[P]MQSim/src/ssd/Address_Mapping_Unit_Page_Level.cpp
// Function: SSD_Components::Address_Mapping_Unit_Page_Level::query_cmt(SSD_Components::NVM_Transaction_Flash*)
bool Address_Mapping_Unit_Page_Level::query_cmt(NVM_Transaction_Flash* transaction)
	{
		stream_id_type stream_id = transaction->Stream_id;
		Stats::total_CMT_queries++;
		Stats::total_CMT_queries_per_stream[stream_id]++;

		if (domains[stream_id]->Mapping_entry_accessible(ideal_mapping_table, stream_id, transaction->LPA))//Either limited or unlimited CMT
		{
			Stats::CMT_hits_per_stream[stream_id]++;
			Stats::CMT_hits++;
			if (transaction->Type == Transaction_Type::READ) {
				Stats::total_readTR_CMT_queries_per_stream[stream_id]++;
				Stats::total_readTR_CMT_queries++;
				Stats::readTR_CMT_hits_per_stream[stream_id]++;
				Stats::readTR_CMT_hits++;
			} else {
				//This is a write transaction
				Stats::total_writeTR_CMT_queries++;
				Stats::total_writeTR_CMT_queries_per_stream[stream_id]++;
				Stats::writeTR_CMT_hits++;
				Stats::writeTR_CMT_hits_per_stream[stream_id]++;
			}

			if (translate_lpa_to_ppa(stream_id, transaction)) {
				return true;
			} else {
				mange_unsuccessful_translation(transaction);
				return false;
			}
		} else {//Limited CMT
			//Maybe we can catch mapping data from an on-the-fly write back request
			if (request_mapping_entry(stream_id, transaction->LPA)) {
				Stats::CMT_miss++;
				Stats::CMT_miss_per_stream[stream_id]++;
				if (transaction->Type == Transaction_Type::READ) {
					Stats::total_readTR_CMT_queries++;
					Stats::total_readTR_CMT_queries_per_stream[stream_id]++;
					Stats::readTR_CMT_miss++;
					Stats::readTR_CMT_miss_per_stream[stream_id]++;
				} else { //This is a write transaction
					Stats::total_writeTR_CMT_queries++;
					Stats::total_writeTR_CMT_queries_per_stream[stream_id]++;
					Stats::writeTR_CMT_miss++;
					Stats::writeTR_CMT_miss_per_stream[stream_id]++;
				}
				if (translate_lpa_to_ppa(stream_id, transaction)) {
					return true;
				} else {
					mange_unsuccessful_translation(transaction);
					return false;
				}
			} else {
				if (transaction->Type == Transaction_Type::READ) {
					Stats::total_readTR_CMT_queries++;
					Stats::total_readTR_CMT_queries_per_stream[stream_id]++;
					Stats::readTR_CMT_miss++;
					Stats::readTR_CMT_miss_per_stream[stream_id]++;
					domains[stream_id]->Waiting_unmapped_read_transactions.insert(std::pair<LPA_type, NVM_Transaction_Flash*>(transaction->LPA, transaction));
				} else {//This is a write transaction
					Stats::total_writeTR_CMT_queries++;
					Stats::total_writeTR_CMT_queries_per_stream[stream_id]++;
					Stats::writeTR_CMT_miss++;
					Stats::writeTR_CMT_miss_per_stream[stream_id]++;
					domains[stream_id]->Waiting_unmapped_program_transactions.insert(std::pair<LPA_type, NVM_Transaction_Flash*>(transaction->LPA, transaction));
				}
			}

			return false;
		}
	}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x10, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movzwl (%rsi), %r15d
leaq 0x41678(%rip), %rax     # 0x63720
incl (%rax)
leaq 0x43eaf(%rip), %rax     # 0x65f60
incl (%rax,%r15,4)
movq 0xa8(%rdi), %rax
movq (%rax,%r15,8), %rdi
movzbl 0x4c(%r14), %esi
movq 0x58(%rbx), %rcx
movl %r15d, %edx
callq 0x26502
testb %al, %al
je 0x22123
leaq 0x42684(%rip), %rax     # 0x64760
incl (%rax,%r15,4)
leaq 0x41621(%rip), %rax     # 0x63708
incl (%rax)
cmpl $0x0, 0x8(%rbx)
je 0x221e9
leaq 0x4162e(%rip), %rax     # 0x63728
incl (%rax)
leal (,%r15,4), %eax
leaq 0x44655(%rip), %rcx     # 0x66760
incl (%rcx,%rax)
leaq 0x415fb(%rip), %rcx     # 0x63710
incl (%rcx)
addq 0x3fe4a(%rip), %rax     # 0x61f68
jmp 0x22215
movq 0x58(%rbx), %rdx
movq %r14, %rdi
movl %r15d, %esi
callq 0x2238a
testb %al, %al
je 0x2219d
leaq 0x415d7(%rip), %rax     # 0x63714
incl (%rax)
leal (,%r15,4), %eax
leaq 0x43212(%rip), %rcx     # 0x65360
incl (%rcx,%rax)
cmpl $0x0, 0x8(%rbx)
leaq 0x415cc(%rip), %rcx     # 0x63728
cmoveq 0x3fdfc(%rip), %rcx     # 0x61f60
leaq 0x445f5(%rip), %rdx     # 0x66760
cmoveq 0x3fdb5(%rip), %rdx     # 0x61f28
leaq 0x415a2(%rip), %rsi     # 0x6371c
cmoveq 0x3fe1e(%rip), %rsi     # 0x61fa0
leaq 0x439d7(%rip), %rdi     # 0x65b60
cmoveq 0x3fdff(%rip), %rdi     # 0x61f90
incl (%rcx)
incl (%rdx,%rax)
incl (%rsi)
incl (%rdi,%rax)
jmp 0x22217
cmpl $0x0, 0x8(%rbx)
je 0x2223a
leaq 0x4157a(%rip), %rax     # 0x63728
incl (%rax)
leal (,%r15,4), %eax
leaq 0x445a1(%rip), %rcx     # 0x66760
incl (%rcx,%rax)
leaq 0x41553(%rip), %rcx     # 0x6371c
incl (%rcx)
leaq 0x4398e(%rip), %rcx     # 0x65b60
incl (%rcx,%rax)
movq 0xa8(%r14), %rax
movq (%rax,%r15,8), %rdi
addq $0x58, %rdi
jmp 0x22277
leal (,%r15,4), %eax
leaq 0x44168(%rip), %rcx     # 0x66360
incl (%rcx,%rax)
leaq 0x41522(%rip), %rcx     # 0x63724
incl (%rcx)
leaq 0x42955(%rip), %rcx     # 0x64b60
incl (%rcx,%rax)
leaq 0x414f7(%rip), %rax     # 0x6370c
incl (%rax)
movq %r14, %rdi
movl %r15d, %esi
movq %rbx, %rdx
callq 0x22296
movl %eax, %ecx
movb $0x1, %al
testb %cl, %cl
jne 0x2228c
movq %r14, %rdi
movq %rbx, %rsi
callq 0x22356
jmp 0x2228a
leaq 0x414e3(%rip), %rax     # 0x63724
incl (%rax)
leal (,%r15,4), %eax
leaq 0x4410e(%rip), %rcx     # 0x66360
incl (%rcx,%rax)
leaq 0x414bc(%rip), %rcx     # 0x63718
incl (%rcx)
leaq 0x434fb(%rip), %rcx     # 0x65760
incl (%rcx,%rax)
movq 0xa8(%r14), %rax
movq (%rax,%r15,8), %rdi
addq $0x28, %rdi
movq 0x58(%rbx), %rax
movq %rsp, %rsi
movq %rax, (%rsi)
movq %rbx, 0x8(%rsi)
callq 0x27eb8
xorl %eax, %eax
addq $0x10, %rsp
popq %rbx
popq %r14
popq %r15
retq