// File: narges64[P]SIMBA/garbage_collection.cpp
// Function: gc_for_plane(ssd_info*, gc_operation*)
void gc_for_plane(ssd_info * ssd, gc_operation * gc_node){
	unsigned int page_move_count = 0;
	local * location = gc_node->location;
	if (find_victim_block(ssd, location) != SUCCESS) {
		printf("Error: invalid block selected for gc \n");
		return;
	}
	int last_write = ssd->channel_head[location->channel]->lun_head[location->lun]->plane_head[location->plane]->blk_head[location->block]->last_write_page; 
	for(int i=0;i<=last_write;i++)
	{
		if(ssd->channel_head[location->channel]->lun_head[location->lun]->plane_head[location->plane]->blk_head[location->block]->page_head[i]->valid_state == true)
		{
			location->page=i;
			if (move_page(ssd, location, gc_node) == FAIL){
				cout << "Error: problem while moving valid pages in GC " << endl;
				return;
			}
			page_move_count++;
		}
	}
	ssd->stats->gc_moved_page += page_move_count;
	
	sub_request * erase_subreq = create_gc_sub_request( ssd, location, ERASE, gc_node);
	ssd->channel_head[location->channel]->lun_head[location->lun]->GCSubs.push_tail(erase_subreq);
	erase_block(ssd,location);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x0, -0x14(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0xa000
cmpl $0x1, %eax
je 0x9e67
leaq 0x5b31(%rip), %rdi      # 0xf98c
movb $0x0, %al
callq 0x2050
jmp 0x9ff6
movq -0x8(%rbp), %rax
movq 0x90(%rax), %rax
movq -0x20(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movq -0x20(%rbp), %rcx
movslq 0x4(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movq -0x20(%rbp), %rcx
movslq 0x8(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rax
movq -0x20(%rbp), %rcx
movslq 0xc(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movl 0x10(%rax), %eax
movl %eax, -0x24(%rbp)
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpl -0x24(%rbp), %eax
jg 0x9f82
movq -0x8(%rbp), %rax
movq 0x90(%rax), %rax
movq -0x20(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movq -0x20(%rbp), %rcx
movslq 0x4(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
movq -0x20(%rbp), %rcx
movslq 0x8(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rax
movq -0x20(%rbp), %rcx
movslq 0xc(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x20(%rax), %rax
movslq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb (%rax), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x1, %eax
jne 0x9f72
movl -0x28(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x10(%rbp), %rdx
callq 0xa230
cmpl $0x0, %eax
jne 0x9f69
movq 0xa087(%rip), %rdi      # 0x13fd0
leaq 0x5a63(%rip), %rsi      # 0xf9b3
callq 0x2110
movq %rax, %rdi
movq 0xa061(%rip), %rsi      # 0x13fc0
callq 0x2150
jmp 0x9ff6
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x9f74
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x9eb9
movl -0x14(%rbp), %ecx
movq -0x8(%rbp), %rax
movq 0x98(%rax), %rax
addl 0xc8(%rax), %ecx
movl %ecx, 0xc8(%rax)
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x10(%rbp), %rcx
movl $0x2, %edx
callq 0xa470
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x90(%rax), %rax
movq -0x20(%rbp), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movq -0x20(%rbp), %rcx
movslq 0x4(%rcx), %rcx
movq (%rax,%rcx,8), %rdi
addq $0x48, %rdi
movq -0x30(%rbp), %rsi
callq 0x50c0
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0xa870
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax)