// 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::Address_Mapping_Unit_Page_Level(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, SSD_Components::FTL*, SSD_Components::NVM_PHY_ONFI*, SSD_Components::Flash_Block_Manager_Base*, bool, unsigned int, SSD_Components::Flash_Plane_Allocation_Scheme_Type, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, std::vector<std::vector<unsigned int, std::allocator<unsigned int>>, std::allocator<std::vector<unsigned int, std::allocator<unsigned int>>>>, std::vector<std::vector<unsigned int, std::allocator<unsigned int>>, std::allocator<std::vector<unsigned int, std::allocator<unsigned int>>>>, std::vector<std::vector<unsigned int, std::allocator<unsigned int>>, std::allocator<std::vector<unsigned int, std::allocator<unsigned int>>>>, std::vector<std::vector<unsigned int, std::allocator<unsigned int>>, std::allocator<std::vector<unsigned int, std::allocator<unsigned int>>>>, unsigned int, unsigned int, unsigned int, unsigned int, double, SSD_Components::CMT_Sharing_Mode, bool)
Address_Mapping_Unit_Page_Level::Address_Mapping_Unit_Page_Level(const sim_object_id_type& id, FTL* ftl, NVM_PHY_ONFI* flash_controller, Flash_Block_Manager_Base* block_manager,
		bool ideal_mapping_table, unsigned int cmt_capacity_in_byte, Flash_Plane_Allocation_Scheme_Type PlaneAllocationScheme,
		unsigned int concurrent_stream_no,
		unsigned int channel_count, unsigned int chip_no_per_channel, unsigned int die_no_per_chip, unsigned int plane_no_per_die,
		std::vector<std::vector<flash_channel_ID_type>> stream_channel_ids, std::vector<std::vector<flash_chip_ID_type>> stream_chip_ids,
		std::vector<std::vector<flash_die_ID_type>> stream_die_ids, std::vector<std::vector<flash_plane_ID_type>> stream_plane_ids,
		unsigned int Block_no_per_plane, unsigned int Page_no_per_block, unsigned int SectorsPerPage, unsigned int PageSizeInByte,
		double Overprovisioning_ratio, CMT_Sharing_Mode sharing_mode, bool fold_large_addresses)
		: Address_Mapping_Unit_Base(id, ftl, flash_controller, block_manager, ideal_mapping_table,
			concurrent_stream_no, channel_count, chip_no_per_channel, die_no_per_chip, plane_no_per_die,
			Block_no_per_plane, Page_no_per_block, SectorsPerPage, PageSizeInByte, Overprovisioning_ratio, sharing_mode, fold_large_addresses)
	{
		_my_instance = this;
		domains = new AddressMappingDomain*[no_of_input_streams];

		Write_transactions_for_overfull_planes = new std::set<NVM_Transaction_Flash_WR*>***[channel_count];
		for (unsigned int channel_id = 0; channel_id < channel_count; channel_id++) {
			Write_transactions_for_overfull_planes[channel_id] = new std::set<NVM_Transaction_Flash_WR*>**[chip_no_per_channel];
			for (unsigned int chip_id = 0; chip_id < chip_no_per_channel; chip_id++) {
				Write_transactions_for_overfull_planes[channel_id][chip_id] = new std::set<NVM_Transaction_Flash_WR*>*[die_no_per_chip];
				for (unsigned int die_id = 0; die_id < die_no_per_chip; die_id++) {
					Write_transactions_for_overfull_planes[channel_id][chip_id][die_id] = new std::set<NVM_Transaction_Flash_WR*>[plane_no_per_die];
				}
			}
		}

		flash_channel_ID_type* channel_ids = NULL;
		flash_channel_ID_type* chip_ids = NULL;
		flash_channel_ID_type* die_ids = NULL;
		flash_channel_ID_type* plane_ids = NULL;
		for (unsigned int domainID = 0; domainID < no_of_input_streams; domainID++) {
			/* Since we want to have the same mapping table entry size for all streams, the entry size
			*  is calculated at this level and then pass it to the constructors of mapping domains
			* entry size = sizeOf(lpa) + sizeOf(ppn) + sizeOf(bit vector that shows written sectors of a page)
			*/
			CMT_entry_size = (unsigned int)std::ceil(((2 * std::log2(total_physical_pages_no)) + sector_no_per_page) / 8);
			//In GTD we do not need to store lpa
			GTD_entry_size = (unsigned int)std::ceil((std::log2(total_physical_pages_no) + sector_no_per_page) / 8);
			no_of_translation_entries_per_page = (SectorsPerPage * SECTOR_SIZE_IN_BYTE) / GTD_entry_size;

			Cached_Mapping_Table* sharedCMT = NULL;
			unsigned int per_stream_cmt_capacity = 0;
			cmt_capacity = cmt_capacity_in_byte / CMT_entry_size;
			switch (sharing_mode) {
				case CMT_Sharing_Mode::SHARED:
					per_stream_cmt_capacity = cmt_capacity;
					sharedCMT = new Cached_Mapping_Table(cmt_capacity);
					break;
				case CMT_Sharing_Mode::EQUAL_SIZE_PARTITIONING:
					per_stream_cmt_capacity = cmt_capacity / no_of_input_streams;
					break;
			}


			channel_ids = new flash_channel_ID_type[stream_channel_ids[domainID].size()];
			for (unsigned int i = 0; i < stream_channel_ids[domainID].size(); i++) {
				if (stream_channel_ids[domainID][i] < channel_count) {
					channel_ids[i] = stream_channel_ids[domainID][i];
				} else {
					PRINT_ERROR("Invalid channel ID specified for I/O flow " << domainID);
				}
			}

			chip_ids = new flash_channel_ID_type[stream_chip_ids[domainID].size()];
			for (unsigned int i = 0; i < stream_chip_ids[domainID].size(); i++) {
				if (stream_chip_ids[domainID][i] < chip_no_per_channel) {
					chip_ids[i] = stream_chip_ids[domainID][i];
				} else {
					PRINT_ERROR("Invalid chip ID specified for I/O flow " << domainID);
				}
			}

			die_ids = new flash_channel_ID_type[stream_die_ids[domainID].size()];
			for (unsigned int i = 0; i < stream_die_ids[domainID].size(); i++) {
				if (stream_die_ids[domainID][i] < die_no_per_chip) {
					die_ids[i] = stream_die_ids[domainID][i];
				} else {
					PRINT_ERROR("Invalid die ID specified for I/O flow " << domainID);
				}
			}

			plane_ids = new flash_channel_ID_type[stream_plane_ids[domainID].size()];
			for (unsigned int i = 0; i < stream_plane_ids[domainID].size(); i++) {
				if (stream_plane_ids[domainID][i] < plane_no_per_die) {
					plane_ids[i] = stream_plane_ids[domainID][i];
				} else {
					PRINT_ERROR("Invalid plane ID specified for I/O flow " << domainID);
				}
			}

			domains[domainID] = new AddressMappingDomain(per_stream_cmt_capacity, CMT_entry_size, no_of_translation_entries_per_page,
				sharedCMT,
				PlaneAllocationScheme,
				channel_ids, (unsigned int)(stream_channel_ids[domainID].size()), chip_ids, (unsigned int)(stream_chip_ids[domainID].size()), die_ids, 
				(unsigned int)(stream_die_ids[domainID].size()), plane_ids, (unsigned int)(stream_plane_ids[domainID].size()),
				Utils::Logical_Address_Partitioning_Unit::PDA_count_allocate_to_flow(domainID), Utils::Logical_Address_Partitioning_Unit::LHA_count_allocate_to_flow_from_device_view(domainID),
				sector_no_per_page);
			delete[] channel_ids;
			delete[] chip_ids;
			delete[] die_ids;
			delete[] plane_ids;
		}
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %rdi, %r15
movl 0x118(%rsp), %r12d
movl 0x108(%rsp), %r13d
movl 0xd0(%rsp), %ebp
movl 0xc8(%rsp), %eax
movl 0xb8(%rsp), %r10d
movl 0x100(%rsp), %r11d
movl 0x110(%rsp), %ebx
subq $0x8, %rsp
movzbl 0x128(%rsp), %r14d
pushq %r14
pushq %r12
pushq %rbx
movq %r13, 0x50(%rsp)
pushq %r13
movq %r10, %r14
pushq %r11
movl 0x128(%rsp), %r10d
pushq %r10
pushq %rbp
movl 0x100(%rsp), %ebx
pushq %rax
pushq %rbx
pushq %r14
movl 0x108(%rsp), %eax
pushq %rax
callq 0x2077c
addq $0x60, %rsp
leaq 0x3fb34(%rip), %rax     # 0x610a8
movq %rax, (%r15)
movq %r15, 0x4105a(%rip)     # 0x625d8
movl 0x50(%r15), %eax
movq %rax, 0x50(%rsp)
leaq (,%rax,8), %rdi
movq %r15, 0x10(%rsp)
callq 0x7030
movq %rax, 0xa8(%r15)
movl %r14d, %eax
movq %rax, 0x18(%rsp)
leaq (,%rax,8), %rdi
callq 0x7030
movq %rax, 0xb8(%r15)
movl %ebx, %eax
movq %rax, 0x20(%rsp)
leaq (,%rax,8), %rax
movq %rax, 0x58(%rsp)
movl 0xc8(%rsp), %eax
movl %eax, %ebp
leaq (,%rbp,8), %rax
movq %rax, 0x28(%rsp)
movl 0xd0(%rsp), %eax
movl %eax, %r13d
imulq $0x30, %r13, %rax
movq %rax, 0x8(%rsp)
leaq 0x8(%rax), %r12
xorl %r14d, %r14d
cmpq 0x18(%rsp), %r14
je 0x216c7
movq 0x58(%rsp), %rdi
callq 0x7030
movq 0x10(%rsp), %rcx
movq 0xb8(%rcx), %rcx
movq %rax, (%rcx,%r14,8)
xorl %ebx, %ebx
cmpq 0x20(%rsp), %rbx
je 0x216bf
movq 0x28(%rsp), %rdi
callq 0x7030
movq 0x10(%rsp), %rcx
movq 0xb8(%rcx), %rcx
movq (%rcx,%r14,8), %rcx
movq %rax, (%rcx,%rbx,8)
xorl %r15d, %r15d
cmpq %rbp, %r15
je 0x216b7
movq %r12, %rdi
callq 0x7030
movq %r13, (%rax)
movl 0xd0(%rsp), %ecx
testl %ecx, %ecx
je 0x21696
leaq 0x10(%rax), %rcx
movq 0x8(%rsp), %rdx
andl $0x0, (%rcx)
andq $0x0, 0x8(%rcx)
movq %rcx, 0x10(%rcx)
movq %rcx, 0x18(%rcx)
andq $0x0, 0x20(%rcx)
addq $0x30, %rcx
addq $-0x30, %rdx
jne 0x21677
addq $0x8, %rax
movq 0x10(%rsp), %rcx
movq 0xb8(%rcx), %rcx
movq (%rcx,%r14,8), %rcx
movq (%rcx,%rbx,8), %rcx
movq %rax, (%rcx,%r15,8)
incq %r15
jmp 0x21653
incq %rbx
jmp 0x21627
incq %r14
jmp 0x21600
movq 0x30(%rsp), %rax
shll $0x9, %eax
movq %rax, 0x30(%rsp)
xorl %r14d, %r14d
movq 0x50(%rsp), %rax
movl %eax, %eax
cmpq %rax, %r14
jae 0x21a76
movq 0x10(%rsp), %rbx
movl 0x84(%rbx), %edi
callq 0x260f3
movl 0x7c(%rbx), %eax
cvtsi2sd %rax, %xmm1
movl 0x84(%rbx), %ebp
addsd %xmm0, %xmm0
addsd %xmm1, %xmm0
movsd 0x24b83(%rip), %xmm1    # 0x46298
mulsd %xmm1, %xmm0
callq 0x7070
cvttsd2si %xmm0, %rax
movl %eax, 0xb0(%rbx)
movl %ebp, %edi
callq 0x260f3
movl 0x7c(%rbx), %eax
movl 0xb0(%rbx), %ebp
cvtsi2sd %rax, %xmm1
addsd %xmm1, %xmm0
mulsd 0x24b4e(%rip), %xmm0    # 0x46298
callq 0x7070
cvttsd2si %xmm0, %rcx
movl %ecx, 0xb4(%rbx)
movq 0x30(%rsp), %rax
xorl %edx, %edx
divl %ecx
movl %eax, 0x50(%rsp)
movl %eax, 0xc0(%rbx)
movl 0xa0(%rsp), %eax
xorl %edx, %edx
movl %ebp, 0x58(%rsp)
divl %ebp
movl %eax, %ebp
movl %eax, 0xa4(%rbx)
movl 0x118(%rsp), %eax
cmpl $0x1, %eax
je 0x217b6
testl %eax, %eax
jne 0x217c9
pushq $0x58
popq %rdi
callq 0x7370
movq %rax, 0x18(%rsp)
movq 0x18(%rsp), %rdi
movl %ebp, %esi
callq 0x209b0
movl %ebp, %eax
movq %rax, 0x48(%rsp)
jmp 0x217db
movl %ebp, %eax
xorl %edx, %edx
movq 0x10(%rsp), %rcx
divl 0x50(%rcx)
movq %rax, 0x48(%rsp)
jmp 0x217d2
movq $0x0, 0x48(%rsp)
movq $0x0, 0x18(%rsp)
movq 0xd8(%rsp), %rax
movq (%rax), %rax
movq %r14, 0x8(%rsp)
imulq $0x18, %r14, %r13
movq 0x8(%rax,%r13), %rdi
movq %rax, %r12
subq (%rax,%r13), %rdi
pushq $-0x1
popq %rax
cmovsq %rax, %rdi
callq 0x7030
movq %rax, %rbx
addq %r13, %r12
movq (%r12), %rax
movq 0x8(%r12), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
xorl %edx, %edx
movl 0xb8(%rsp), %edi
movq %r13, %r8
movl %edx, %edx
cmpq %rdx, %rcx
jbe 0x21842
movl (%rax,%rdx,4), %esi
cmpl %edi, %esi
jae 0x21a85
movl %esi, (%rbx,%rdx,4)
incl %edx
jmp 0x21829
movq %r12, 0x40(%rsp)
movq 0xe0(%rsp), %rax
movq (%rax), %rax
movq 0x8(%rax,%r8), %rdi
movq %rax, %r14
subq (%rax,%r8), %rdi
pushq $-0x1
popq %rax
cmovsq %rax, %rdi
movq %r8, %rbp
callq 0x7030
movq %rax, %r13
movq %r14, %r9
addq %rbp, %r9
movq (%r9), %rax
movq 0x8(%r9), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
xorl %edx, %edx
movl 0xc0(%rsp), %edi
movq %rbp, %r14
movl %edx, %edx
cmpq %rdx, %rcx
jbe 0x218ab
movl (%rax,%rdx,4), %esi
cmpl %edi, %esi
jae 0x21ad1
movl %esi, (%r13,%rdx,4)
incl %edx
jmp 0x21890
movq %r9, 0x38(%rsp)
movq 0xe8(%rsp), %rax
movq (%rax), %rax
movq 0x8(%rax,%r14), %rdi
movq %rax, %r15
subq (%rax,%r14), %rdi
pushq $-0x1
popq %rax
cmovsq %rax, %rdi
callq 0x7030
movq %rax, %rbp
addq %r14, %r15
movq (%r15), %rax
movq %r15, 0x60(%rsp)
movq 0x8(%r15), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
xorl %edx, %edx
movq %r14, %r12
movl %edx, %edx
cmpq %rdx, %rcx
jbe 0x21912
movl (%rax,%rdx,4), %esi
movl 0xc8(%rsp), %edi
cmpl %edi, %esi
jae 0x21b1d
movl %esi, (%rbp,%rdx,4)
incl %edx
jmp 0x218f1
movq 0xf0(%rsp), %rax
movq (%rax), %r14
movq 0x8(%r14,%r12), %rdi
subq (%r14,%r12), %rdi
pushq $-0x1
popq %rax
cmovsq %rax, %rdi
callq 0x7030
movq %rax, %r15
addq %r12, %r14
movq (%r14), %rax
movq 0x8(%r14), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
xorl %edx, %edx
movl %edx, %edx
cmpq %rdx, %rcx
jbe 0x21969
movl (%rax,%rdx,4), %esi
movl 0xd0(%rsp), %edi
cmpl %edi, %esi
jae 0x21b66
movl %esi, (%r15,%rdx,4)
incl %edx
jmp 0x21948
movl $0x270, %edi            # imm = 0x270
callq 0x7370
movq %rax, 0x20(%rsp)
movq %r14, %rcx
movq %rbx, 0x28(%rsp)
movq 0x40(%rsp), %r12
movq 0x8(%r12), %rax
subq (%r12), %rax
movq %rax, 0x40(%rsp)
movq 0x38(%rsp), %rax
movq 0x8(%rax), %rbx
subq (%rax), %rbx
movq 0x60(%rsp), %rax
movq 0x8(%rax), %r14
subq (%rax), %r14
movq 0x8(%rcx), %r12
subq (%rcx), %r12
movzwl 0x8(%rsp), %edi
callq 0x410b4
movq %rax, 0x38(%rsp)
movzwl 0x8(%rsp), %edi
callq 0x41032
movq 0x40(%rsp), %r11
shrq $0x2, %r11
shrq $0x2, %rbx
shrq $0x2, %r14
shrq $0x2, %r12
movq 0x10(%rsp), %rcx
movl 0x7c(%rcx), %r10d
subq $0x8, %rsp
movq 0x28(%rsp), %rdi
movq 0x50(%rsp), %rsi
movl 0x60(%rsp), %edx
movl 0x58(%rsp), %ecx
movq 0x20(%rsp), %r8
movl 0xb0(%rsp), %r9d
pushq %r10
pushq %rax
pushq 0x50(%rsp)
pushq %r12
pushq %r15
pushq %r14
pushq %rbp
pushq %rbx
pushq %r13
pushq %r11
pushq 0x80(%rsp)
callq 0x20ef4
addq $0x60, %rsp
movq 0x10(%rsp), %rbx
movq 0xa8(%rbx), %rax
movq 0x8(%rsp), %r14
movq 0x20(%rsp), %rcx
movq %rcx, (%rax,%r14,8)
movq 0x28(%rsp), %rdi
callq 0x7430
movq %r13, %rdi
callq 0x7430
movq %rbp, %rdi
callq 0x7430
movq %r15, %rdi
callq 0x7430
incq %r14
movl 0x50(%rbx), %eax
jmp 0x216dc
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x40564(%rip), %rdi     # 0x61ff0
leaq 0x22af5(%rip), %rsi     # 0x44588
callq 0x7360
movq 0x40551(%rip), %rdi     # 0x61ff0
leaq 0x24c15(%rip), %rsi     # 0x466bb
callq 0x7360
movq %rax, %rdi
movq 0x8(%rsp), %rsi
callq 0x7270
movq %rax, %rdi
callq 0x71a0
movq 0x40509(%rip), %rdi     # 0x61fd0
callq 0x73d0
jmp 0x21bad
movq 0x40518(%rip), %rdi     # 0x61ff0
leaq 0x22aa9(%rip), %rsi     # 0x44588
callq 0x7360
movq 0x40505(%rip), %rdi     # 0x61ff0
leaq 0x24bf4(%rip), %rsi     # 0x466e6
callq 0x7360
movq %rax, %rdi
movq 0x8(%rsp), %rsi
callq 0x7270
movq %rax, %rdi
callq 0x71a0
movq 0x404bd(%rip), %rdi     # 0x61fd0
callq 0x73d0
jmp 0x21bad
movq 0x404cc(%rip), %rdi     # 0x61ff0
leaq 0x22a5d(%rip), %rsi     # 0x44588
callq 0x7360
movq 0x404b9(%rip), %rdi     # 0x61ff0
leaq 0x24bd0(%rip), %rsi     # 0x4670e
callq 0x7360
movq %rax, %rdi
movq 0x8(%rsp), %rsi
callq 0x7270
movq %rax, %rdi
callq 0x71a0
movq 0x40471(%rip), %rdi     # 0x61fd0
callq 0x73d0
jmp 0x21bad
movq 0x40483(%rip), %rdi     # 0x61ff0
leaq 0x22a14(%rip), %rsi     # 0x44588
callq 0x7360
movq 0x40470(%rip), %rdi     # 0x61ff0
leaq 0x24bae(%rip), %rsi     # 0x46735
callq 0x7360
movq %rax, %rdi
movq 0x8(%rsp), %rsi
callq 0x7270
movq %rax, %rdi
callq 0x71a0
movq 0x40428(%rip), %rdi     # 0x61fd0
callq 0x73d0
pushq $0x1
popq %rdi
callq 0x73e0
jmp 0x21bd4
jmp 0x21bd4
movq %rax, %r14
movq 0x20(%rsp), %rdi
callq 0x7340
jmp 0x21bd7
jmp 0x21bd4
jmp 0x21bd4
jmp 0x21bd4
jmp 0x21bd4
jmp 0x21bd4
jmp 0x21bd4
movq %rax, %r14
movq 0x10(%rsp), %rdi
callq 0x2089e
movq %r14, %rdi
callq 0x75d0
nop