// File: narges64[P]SIMBA/ftl.cpp
// Function: full_write_preconditioning(ssd_info*, bool)
void full_write_preconditioning(ssd_info * ssd, bool seq){
	unsigned int total_size = ssd->parameter->lun_num * ssd->parameter->plane_lun *
						ssd->parameter->block_plane * ssd->parameter->page_block;
	total_size = total_size * (1-ssd->parameter->overprovide);
	cerr << "full write for total size " << total_size << " page ";
	// add write to table
	int lpn = 0;
	int ppn = -1;
	local * location = new local(0,0,0,0,0);
	for (int i = 0; i <  total_size; i++){
		if (!seq){
			if ((invalid_old_page(ssd, lpn, location) != SUCCESS)){
				#if DEBUG
				cout << "fail in invalid old page" << endl;
				#endif 
			}
			ppn = get_new_ppn (ssd, lpn, location, true);
			if (ppn == -1) {
				cout << "fail in precondition " << endl;
			}
		}else {
			if ((invalid_old_page(ssd, lpn, location) == SUCCESS)){
				#if DEBUG 
				cout << "seqential should not see the old page " << endl;
				#endif 
			}
			ppn = get_new_ppn(ssd, lpn, NULL, true);
			if (ppn == -1)
				cout << "fail in precondition 2" << endl;
		}
		if (write_page(ssd, lpn, ppn) == FAIL)
			cout << "full write precondition fail in write_page " << endl;
		bool gc = check_need_gc(ssd, ppn);
		if (gc) {
			if (seq) cerr << "should not have GC in sequential preconditioning " << endl;
			local * location = new local(0,0,0);
			find_location(ssd, ppn, location);
			pre_process_gc(ssd, location);
			delete location;
 		}
		if(seq) {
			lpn++;
			lpn = lpn % total_size;
		}else
			lpn = rand() % total_size;
	}
	cerr << "is complete. erase count: " <<  ssd->stats->flash_erase_count
				<< ". move count: " << ssd->stats->gc_moved_page << endl;
	ssd->stats->flash_erase_count  = 0;
	ssd->stats->gc_moved_page = 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movb %sil, %al
movq %rdi, -0x8(%rbp)
andb $0x1, %al
movb %al, -0x9(%rbp)
movq -0x8(%rbp), %rax
movq 0x58(%rax), %rcx
movl 0x88(%rcx), %eax
movl 0x22c(%rcx), %edx
imull %edx, %eax
movl 0x230(%rcx), %edx
imull %edx, %eax
movl 0x234(%rcx), %ecx
imull %ecx, %eax
movl %eax, -0x10(%rbp)
movl -0x10(%rbp), %eax
cvtsi2ss %rax, %xmm0
movq -0x8(%rbp), %rax
movq 0x58(%rax), %rax
movss 0x25c(%rax), %xmm2
movss 0x9b20(%rip), %xmm1     # 0xf010
subss %xmm2, %xmm1
mulss %xmm1, %xmm0
cvttss2si %xmm0, %rax
movl %eax, -0x10(%rbp)
movq 0xeae9(%rip), %rdi      # 0x13ff0
leaq 0x9f8d(%rip), %rsi      # 0xf49b
callq 0x2110
movq %rax, %rdi
movl -0x10(%rbp), %esi
callq 0x21c0
movq %rax, %rdi
leaq 0xa5fc(%rip), %rsi      # 0xfb24
callq 0x2110
movl $0x0, -0x14(%rbp)
movl $0xffffffff, -0x18(%rbp) # imm = 0xFFFFFFFF
movl $0x18, %edi
callq 0x2130
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x48(%rbp)
xorl %r9d, %r9d
movl %r9d, %esi
movl %r9d, %edx
movl %r9d, %ecx
movl %r9d, %r8d
callq 0x8ae0
jmp 0x5565
movq -0x48(%rbp), %rax
movq %rax, -0x20(%rbp)
movl $0x0, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x10(%rbp), %eax
jae 0x5795
testb $0x1, -0x9(%rbp)
jne 0x55fe
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
movq -0x20(%rbp), %rdx
callq 0x5840
cmpl $0x1, %eax
je 0x55bc
jmp 0x55bc
movq -0x48(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
movl $0x18, %esi
callq 0x2140
jmp 0x582a
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
movq -0x20(%rbp), %rdx
movl $0x1, %ecx
callq 0x5960
movl %eax, -0x18(%rbp)
cmpl $-0x1, -0x18(%rbp)
jne 0x55fc
movq 0xe9ef(%rip), %rdi      # 0x13fd0
leaq 0x9ece(%rip), %rsi      # 0xf4b6
callq 0x2110
movq %rax, %rdi
movq 0xe9c9(%rip), %rsi      # 0x13fc0
callq 0x2150
jmp 0x5657
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
movq -0x20(%rbp), %rdx
callq 0x5840
cmpl $0x1, %eax
jne 0x5615
jmp 0x5615
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
xorl %eax, %eax
movl %eax, %edx
movl $0x1, %ecx
callq 0x5960
movl %eax, -0x18(%rbp)
cmpl $-0x1, -0x18(%rbp)
jne 0x5655
movq 0xe996(%rip), %rdi      # 0x13fd0
leaq 0x9e8b(%rip), %rsi      # 0xf4cc
callq 0x2110
movq %rax, %rdi
movq 0xe970(%rip), %rsi      # 0x13fc0
callq 0x2150
jmp 0x5657
movq -0x8(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x18(%rbp), %edx
callq 0x5ac0
cmpl $0x0, %eax
jne 0x568d
movq 0xe95e(%rip), %rdi      # 0x13fd0
leaq 0x9e6a(%rip), %rsi      # 0xf4e3
callq 0x2110
movq %rax, %rdi
movq 0xe938(%rip), %rsi      # 0x13fc0
callq 0x2150
movq -0x8(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0x5b20
andb $0x1, %al
movb %al, -0x31(%rbp)
testb $0x1, -0x31(%rbp)
je 0x575c
testb $0x1, -0x9(%rbp)
je 0x56d0
movq 0xe93b(%rip), %rdi      # 0x13ff0
leaq 0x9e53(%rip), %rsi      # 0xf50f
callq 0x2110
movq %rax, %rdi
movq 0xe8f5(%rip), %rsi      # 0x13fc0
callq 0x2150
movl $0x18, %edi
callq 0x2130
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x50(%rbp)
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x8b20
jmp 0x56f1
movq -0x50(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x8(%rbp), %rdi
movl -0x18(%rbp), %esi
movq -0x40(%rbp), %rdx
callq 0x5c70
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0xb5c0
movq -0x40(%rbp), %rax
movq %rax, -0x58(%rbp)
cmpq $0x0, %rax
je 0x573b
movq -0x58(%rbp), %rdi
callq 0x8b50
movq -0x58(%rbp), %rdi
movl $0x18, %esi
callq 0x2140
jmp 0x575c
movq -0x50(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x28(%rbp)
movl %eax, -0x2c(%rbp)
movl $0x18, %esi
callq 0x2140
jmp 0x582a
testb $0x1, -0x9(%rbp)
je 0x5778
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
xorl %edx, %edx
divl -0x10(%rbp)
movl %edx, -0x14(%rbp)
jmp 0x5785
callq 0x2090
xorl %edx, %edx
divl -0x10(%rbp)
movl %edx, -0x14(%rbp)
jmp 0x5787
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x5574
movq 0xe854(%rip), %rdi      # 0x13ff0
leaq 0x9d9e(%rip), %rsi      # 0xf541
callq 0x2110
movq %rax, %rdi
movq -0x8(%rbp), %rax
movq 0x98(%rax), %rax
movq 0x98(%rax), %rsi
callq 0x2240
movq %rax, %rdi
leaq 0x9d90(%rip), %rsi      # 0xf55c
callq 0x2110
movq %rax, %rdi
movq -0x8(%rbp), %rax
movq 0x98(%rax), %rax
movl 0xc8(%rax), %esi
callq 0x2220
movq %rax, %rdi
movq 0xe7cc(%rip), %rsi      # 0x13fc0
callq 0x2150
movq -0x8(%rbp), %rax
movq 0x98(%rax), %rax
movq $0x0, 0x98(%rax)
movq -0x8(%rbp), %rax
movq 0x98(%rax), %rax
movl $0x0, 0xc8(%rax)
addq $0x60, %rsp
popq %rbp
retq
movq -0x28(%rbp), %rdi
callq 0x2230
nopw %cs:(%rax,%rax)