// File: CMU-SAFARI[P]MQSim/src/ssd/GC_and_WL_Unit_Base.cpp
// Function: SSD_Components::GC_and_WL_Unit_Base::GC_and_WL_Unit_Base(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, SSD_Components::Address_Mapping_Unit_Base*, SSD_Components::Flash_Block_Manager_Base*, SSD_Components::TSU_Base*, SSD_Components::NVM_PHY_ONFI*, SSD_Components::GC_Block_Selection_Policy_Type, double, bool, double, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, bool, double, unsigned int, bool, bool, unsigned int, int)
GC_and_WL_Unit_Base::GC_and_WL_Unit_Base(const sim_object_id_type& id,
		Address_Mapping_Unit_Base* address_mapping_unit, Flash_Block_Manager_Base* block_manager, TSU_Base* tsu, NVM_PHY_ONFI* flash_controller,
		GC_Block_Selection_Policy_Type block_selection_policy, double gc_threshold, bool preemptible_gc_enabled, double gc_hard_threshold,
		unsigned int channel_count, unsigned int chip_no_per_channel, unsigned int die_no_per_chip, unsigned int plane_no_per_die,
		unsigned int block_no_per_plane, unsigned int page_no_per_block, unsigned int sector_no_per_page, 
		bool use_copyback, double rho, unsigned int max_ongoing_gc_reqs_per_plane, bool dynamic_wearleveling_enabled, bool static_wearleveling_enabled, unsigned int static_wearleveling_threshold, int seed) :
		Sim_Object(id), address_mapping_unit(address_mapping_unit), block_manager(block_manager), tsu(tsu), flash_controller(flash_controller), force_gc(false),
		block_selection_policy(block_selection_policy), gc_threshold(gc_threshold),	use_copyback(use_copyback), 
		preemptible_gc_enabled(preemptible_gc_enabled), gc_hard_threshold(gc_hard_threshold),
		random_generator(seed), max_ongoing_gc_reqs_per_plane(max_ongoing_gc_reqs_per_plane),
		channel_count(channel_count), chip_no_per_channel(chip_no_per_channel), die_no_per_chip(die_no_per_chip), plane_no_per_die(plane_no_per_die),
		block_no_per_plane(block_no_per_plane), pages_no_per_block(page_no_per_block), sector_no_per_page(sector_no_per_page),
		dynamic_wearleveling_enabled(dynamic_wearleveling_enabled), static_wearleveling_enabled(static_wearleveling_enabled), static_wearleveling_threshold(static_wearleveling_threshold)
	{
		_my_instance = this;
		block_pool_gc_threshold = (unsigned int)(gc_threshold * (double)block_no_per_plane);
		if (block_pool_gc_threshold < 1) {
			block_pool_gc_threshold = 1;
		}
		block_pool_gc_hard_threshold = (unsigned int)(gc_hard_threshold * (double)block_no_per_plane);
		if (block_pool_gc_hard_threshold < 1) {
			block_pool_gc_hard_threshold = 1;
		}
		random_pp_threshold = (unsigned int)(rho * pages_no_per_block);
		if (block_pool_gc_threshold < max_ongoing_gc_reqs_per_plane) {
			block_pool_gc_threshold = max_ongoing_gc_reqs_per_plane;
		}
	}

// Assembly:
pushq %rbp
pushq %rbx
subq $0x88, %rsp
movq %rcx, 0x8(%rsp)
movq %rdx, %r10
movq %rsi, %r11
movq %rdi, %rbx
movq 0x8(%rsp), %rdi
movl 0x110(%rsp), %eax
movl 0x108(%rsp), %eax
movb 0x100(%rsp), %al
movb 0xf8(%rsp), %cl
movl 0xf0(%rsp), %edx
movb 0xe8(%rsp), %dl
movl 0xe0(%rsp), %esi
movl 0xd8(%rsp), %esi
movl 0xd0(%rsp), %esi
movl 0xc8(%rsp), %esi
movl 0xc0(%rsp), %esi
movl 0xb8(%rsp), %esi
movl 0xb0(%rsp), %esi
movb 0xa8(%rsp), %sil
movl 0xa0(%rsp), %ebp
movq %rbx, 0x80(%rsp)
movq %r11, 0x78(%rsp)
movq %r10, 0x70(%rsp)
movq %rdi, 0x68(%rsp)
movq %r8, 0x60(%rsp)
movq %r9, 0x58(%rsp)
movsd %xmm0, 0x50(%rsp)
andb $0x1, %sil
movb %sil, 0x4f(%rsp)
movsd %xmm1, 0x40(%rsp)
andb $0x1, %dl
movb %dl, 0x3f(%rsp)
movsd %xmm2, 0x30(%rsp)
andb $0x1, %cl
movb %cl, 0x2f(%rsp)
andb $0x1, %al
movb %al, 0x2e(%rsp)
movq 0x80(%rsp), %rdi
movq %rdi, 0x10(%rsp)
movq 0x78(%rsp), %rsi
callq 0x1fd60
movq 0x10(%rsp), %rdi
leaq 0x58f97(%rip), %rax     # 0xd9500
movq %rax, (%rdi)
movl 0xa0(%rsp), %eax
movl %eax, 0x2c(%rdi)
movq 0x70(%rsp), %rax
movq %rax, 0x30(%rdi)
movq 0x68(%rsp), %rax
movq %rax, 0x38(%rdi)
movq 0x60(%rsp), %rax
movq %rax, 0x40(%rdi)
movq 0x58(%rsp), %rax
movq %rax, 0x48(%rdi)
movb $0x0, 0x50(%rdi)
movsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x58(%rdi)
movb 0x3f(%rsp), %al
andb $0x1, %al
movb %al, 0x64(%rdi)
movb 0x2f(%rsp), %al
andb $0x1, %al
movb %al, 0x65(%rdi)
movb 0x2e(%rsp), %al
andb $0x1, %al
movb %al, 0x66(%rdi)
movl 0x108(%rsp), %eax
movl %eax, 0x68(%rdi)
movb 0x4f(%rsp), %al
andb $0x1, %al
movb %al, 0x6c(%rdi)
movsd 0x40(%rsp), %xmm0
movsd %xmm0, 0x70(%rdi)
movl 0xf0(%rsp), %eax
movl %eax, 0x7c(%rdi)
addq $0x88, %rdi
movl 0x110(%rsp), %esi
callq 0xa6e40
jmp 0x80601
movq 0x10(%rsp), %rdi
addq $0xa0, %rdi
callq 0x81cb0
jmp 0x80614
movq 0x10(%rsp), %rax
movl 0xb0(%rsp), %ecx
movl %ecx, 0xf4(%rax)
movl 0xb8(%rsp), %ecx
movl %ecx, 0xf8(%rax)
movl 0xc0(%rsp), %ecx
movl %ecx, 0xfc(%rax)
movl 0xc8(%rsp), %ecx
movl %ecx, 0x100(%rax)
movl 0xd0(%rsp), %ecx
movl %ecx, 0x104(%rax)
movl 0xd8(%rsp), %ecx
movl %ecx, 0x108(%rax)
movl 0xe0(%rsp), %ecx
movl %ecx, 0x10c(%rax)
movq %rax, 0x5a08d(%rip)     # 0xda708
movsd 0x50(%rsp), %xmm0
movl 0xd0(%rsp), %ecx
cvtsi2sd %rcx, %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
movl %ecx, 0x60(%rax)
cmpl $0x1, 0x60(%rax)
jae 0x806c7
movq 0x10(%rsp), %rax
movl $0x1, 0x60(%rax)
jmp 0x806c7
movq 0x10(%rsp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x20(%rsp)
movl %eax, 0x1c(%rsp)
callq 0x1ff90
jmp 0x80746
movq 0x10(%rsp), %rax
movsd 0x40(%rsp), %xmm0
movl 0xd0(%rsp), %ecx
cvtsi2sd %rcx, %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
movl %ecx, 0x78(%rax)
cmpl $0x1, 0x78(%rax)
jae 0x806fc
movq 0x10(%rsp), %rax
movl $0x1, 0x78(%rax)
movq 0x10(%rsp), %rax
movsd 0x30(%rsp), %xmm0
movl 0x108(%rax), %ecx
cvtsi2sd %rcx, %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
movl %ecx, 0xf0(%rax)
movl 0x60(%rax), %eax
cmpl 0xf0(%rsp), %eax
jae 0x8073c
movq 0x10(%rsp), %rax
movl 0xf0(%rsp), %ecx
movl %ecx, 0x60(%rax)
addq $0x88, %rsp
popq %rbx
popq %rbp
retq
movq 0x20(%rsp), %rdi
callq 0x8770