// File: /workspace/github_cpp_makefile_star2_O3/narges64[P]SIMBA/ftl.cpp
// Function: update_physical_page(ssd_info*, int, int)
STATE update_physical_page(ssd_info * ssd, const int ppn, const int lpn){
	local * location = new local(0,0,0);
	find_location(ssd, ppn, location);

	int c = location->channel;
	int l = location->lun;
	int p = location->plane;
	int b = location->block;
	int pg = location->page;

	blk_info * block = ssd->channel_head[c]->lun_head[l]->plane_head[p]->blk_head[b];

	if (lpn != -1) {
		if (block->last_write_page > pg) {
			cout << "update physical page, writing backward " << block->last_write_page  << "  "  << pg<< endl;
			return FAIL;
		}
		ssd->channel_head[c]->lun_head[l]->plane_head[p]->blk_head[b]->page_head[pg]->lpn=lpn;
		ssd->channel_head[c]->lun_head[l]->plane_head[p]->blk_head[b]->page_head[pg]->valid_state=true;

		ssd->channel_head[c]->lun_head[l]->plane_head[p]->free_page--;
		ssd->stats->flash_prog_count++;
		ssd->channel_head[c]->program_count++;
		ssd->channel_head[c]->lun_head[l]->program_count++;
		ssd->channel_head[c]->lun_head[l]->plane_head[p]->program_count++;
	}else {

		if (block->page_head[pg]->lpn == -1 || block->page_head[pg]->valid_state == false) {
			cout << "invalidating has problem, the page is already invalid or free " << endl;
			return FAIL;
		}

		block->page_head[pg]->lpn=-1;
		if (block->page_head[pg]->valid_state){
			block->invalid_page_num++;
		}
		block->page_head[pg]->valid_state=false;
		ssd->channel_head[c]->lun_head[l]->plane_head[p]->invalid_page++;

	}
	delete location;
	return SUCCESS;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %edx, %ebp
movl %esi, %r14d
movq %rdi, %r15
movl $0x18, %edi
callq 0x2190
movq %rax, %rbx
movq $0x0, (%rax)
movl $0x0, 0x8(%rax)
movq %r15, %rdi
movl %r14d, %esi
movq %rax, %rdx
callq 0x4af9
movslq (%rbx), %rax
movslq 0x4(%rbx), %rdx
movslq 0x8(%rbx), %rsi
movslq 0xc(%rbx), %rdi
movslq 0x10(%rbx), %r14
movq 0x90(%r15), %rcx
movq (%rcx,%rax,8), %rcx
movq 0x50(%rcx), %rax
movq (%rax,%rdx,8), %rdx
movq (%rdx), %rax
movq (%rax,%rsi,8), %rax
movq 0x20(%rax), %rsi
movq (%rsi,%rdi,8), %r12
cmpl $-0x1, %ebp
je 0x60a6
cmpl %r14d, 0x10(%r12)
jle 0x60d0
movq 0x7f78(%rip), %rbx      # 0xdfd0
leaq 0x46b8(%rip), %rsi      # 0xa717
movl $0x27, %edx
movq %rbx, %rdi
callq 0x21e0
movl 0x10(%r12), %esi
movq %rbx, %rdi
callq 0x22d0
movq %rax, %rbx
leaq 0x44b0(%rip), %rsi      # 0xa533
movl $0x2, %edx
movq %rax, %rdi
callq 0x21e0
movq %rbx, %rdi
movl %r14d, %esi
callq 0x22d0
movq %rax, %rbx
movq (%rax), %rax
jmp 0x6132
movq 0x20(%r12), %rcx
movq (%rcx,%r14,8), %rcx
cmpl $-0x1, 0x4(%rcx)
je 0x6114
cmpb $0x0, (%rcx)
je 0x6114
movl $0xffffffff, 0x4(%rcx)  # imm = 0xFFFFFFFF
incl 0x8(%r12)
movb $0x0, (%rcx)
movl $0x8, %ecx
jmp 0x60fc
movq 0x20(%r12), %rsi
movq (%rsi,%r14,8), %rsi
movl %ebp, 0x4(%rsi)
movb $0x1, (%rsi)
decq (%rax)
movq 0x98(%r15), %rsi
incq 0x88(%rsi)
incq 0x10(%rcx)
incl 0xc(%rdx)
movl $0x40, %ecx
incq (%rax,%rcx)
movl $0x18, %esi
movq %rbx, %rdi
callq 0x21a0
movl $0x1, %eax
jmp 0x6158
movq 0x7eb5(%rip), %rbx      # 0xdfd0
leaq 0x461d(%rip), %rsi      # 0xa73f
movl $0x3e, %edx
movq %rbx, %rdi
callq 0x21e0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2150
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2050
movq %rax, %rdi
callq 0x20f0
xorl %eax, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq