// File: /workspace/github_c_makefile_star2_O0/lb3361[P]dosfs/ff.c
// Function: remove_chain
static FRESULT remove_chain (	/* FR_OK(0):succeeded, !=0:error */
	FFOBJID* obj,		/* Corresponding object */
	DWORD clst,			/* Cluster to remove a chain from */
	DWORD pclst			/* Previous cluster of clst (0 if entire chain) */
)
{
	FRESULT res = FR_OK;
	DWORD nxt;
	FATFS *fs = obj->fs;
#if FF_FS_EXFAT || FF_USE_TRIM
	DWORD scl = clst, ecl = clst;
#endif
#if FF_USE_TRIM
	LBA_t rt[2];
#endif

	if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR;	/* Check if in valid range */

	/* Mark the previous cluster 'EOC' on the FAT if it exists */
	if (pclst != 0 && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT || obj->stat != 2)) {
		res = put_fat(fs, pclst, 0xFFFFFFFF);
		if (res != FR_OK) return res;
	}

	/* Remove the chain */
	do {
		nxt = get_fat(obj, clst);			/* Get cluster status */
		if (nxt == 0) break;				/* Empty cluster? */
		if (nxt == 1) return FR_INT_ERR;	/* Internal error? */
		if (nxt == 0xFFFFFFFF) return FR_DISK_ERR;	/* Disk error? */
		if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) {
			res = put_fat(fs, clst, 0);		/* Mark the cluster 'free' on the FAT */
			if (res != FR_OK) return res;
		}
		if (fs->free_clst < fs->n_fatent - 2) {	/* Update FSINFO */
			fs->free_clst++;
			fs->fsi_flag |= 1;
		}
#if FF_FS_EXFAT || FF_USE_TRIM
		if (ecl + 1 == nxt) {	/* Is next cluster contiguous? */
			ecl = nxt;
		} else {				/* End of contiguous cluster block */
#if FF_FS_EXFAT
			if (fs->fs_type == FS_EXFAT) {
				res = change_bitmap(fs, scl, ecl - scl + 1, 0);	/* Mark the cluster block 'free' on the bitmap */
				if (res != FR_OK) return res;
			}
#endif
#if FF_USE_TRIM
			rt[0] = clst2sect(fs, scl);					/* Start of data area to be freed */
			rt[1] = clst2sect(fs, ecl) + fs->csize - 1;	/* End of data area to be freed */
			disk_ioctl(fs->pdrv, CTRL_TRIM, rt);		/* Inform storage device that the data in the block may be erased */
#endif
			scl = ecl = nxt;
		}
#endif
		clst = nxt;					/* Next cluster */
	} while (clst < fs->n_fatent);	/* Repeat while not the last link */

#if FF_FS_EXFAT
	/* Some post processes for chain status */
	if (fs->fs_type == FS_EXFAT) {
		if (pclst == 0) {	/* Has the entire chain been removed? */
			obj->stat = 0;		/* Change the chain status 'initial' */
		} else {
			if (obj->stat == 0) {	/* Is it a fragmented chain from the beginning of this session? */
				clst = obj->sclust;		/* Follow the chain to check if it gets contiguous */
				while (clst != pclst) {
					nxt = get_fat(obj, clst);
					if (nxt < 2) return FR_INT_ERR;
					if (nxt == 0xFFFFFFFF) return FR_DISK_ERR;
					if (nxt != clst + 1) break;	/* Not contiguous? */
					clst++;
				}
				if (clst == pclst) {	/* Has the chain got contiguous again? */
					obj->stat = 2;		/* Change the chain status 'contiguous' */
				}
			} else {
				if (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) {	/* Was the chain fragmented in this session and got contiguous again? */
					obj->stat = 2;	/* Change the chain status 'contiguous' */
				}
			}
		}
	}
#endif
	return FR_OK;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x28(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x2c(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x30(%rbp)
cmpl $0x2, -0x14(%rbp)
jb 0x6182
movl -0x14(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl 0x28(%rcx), %eax
jb 0x618e
movl $0x2, -0x4(%rbp)
jmp 0x63bd
cmpl $0x0, -0x18(%rbp)
je 0x61d4
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x4, %eax
jne 0x61ad
movq -0x10(%rbp), %rax
movzbl 0xb(%rax), %eax
cmpl $0x2, %eax
je 0x61d4
movq -0x28(%rbp), %rdi
movl -0x18(%rbp), %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0xf180
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x61d2
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x63bd
jmp 0x61d4
jmp 0x61d6
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x6560
movl %eax, -0x20(%rbp)
cmpl $0x0, -0x20(%rbp)
jne 0x61f0
jmp 0x62df
cmpl $0x1, -0x20(%rbp)
jne 0x6202
movl $0x2, -0x4(%rbp)
jmp 0x63bd
cmpl $-0x1, -0x20(%rbp)
jne 0x6214
movl $0x1, -0x4(%rbp)
jmp 0x63bd
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x4, %eax
je 0x6244
movq -0x28(%rbp), %rdi
movl -0x14(%rbp), %esi
xorl %edx, %edx
callq 0xf180
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x6242
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x63bd
jmp 0x6244
movq -0x28(%rbp), %rax
movl 0x24(%rax), %eax
movq -0x28(%rbp), %rcx
movl 0x28(%rcx), %ecx
subl $0x2, %ecx
cmpl %ecx, %eax
jae 0x6274
movq -0x28(%rbp), %rax
movl 0x24(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x24(%rax)
movq -0x28(%rbp), %rax
movzbl 0x4(%rax), %ecx
orl $0x1, %ecx
movb %cl, 0x4(%rax)
movl -0x30(%rbp), %eax
addl $0x1, %eax
cmpl -0x20(%rbp), %eax
jne 0x6287
movl -0x20(%rbp), %eax
movl %eax, -0x30(%rbp)
jmp 0x62c9
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x4, %eax
jne 0x62c0
movq -0x28(%rbp), %rdi
movl -0x2c(%rbp), %esi
movl -0x30(%rbp), %edx
subl -0x2c(%rbp), %edx
addl $0x1, %edx
xorl %ecx, %ecx
callq 0xf410
movl %eax, -0x1c(%rbp)
cmpl $0x0, -0x1c(%rbp)
je 0x62be
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x63bd
jmp 0x62c0
movl -0x20(%rbp), %eax
movl %eax, -0x30(%rbp)
movl %eax, -0x2c(%rbp)
movl -0x20(%rbp), %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl 0x28(%rcx), %eax
jb 0x61d6
movq -0x28(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x4, %eax
jne 0x63b6
cmpl $0x0, -0x18(%rbp)
jne 0x6302
movq -0x10(%rbp), %rax
movb $0x0, 0xb(%rax)
jmp 0x63b4
movq -0x10(%rbp), %rax
movzbl 0xb(%rax), %eax
cmpl $0x0, %eax
jne 0x637a
movq -0x10(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x18(%rbp), %eax
je 0x6368
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x6560
movl %eax, -0x20(%rbp)
cmpl $0x2, -0x20(%rbp)
jae 0x633f
movl $0x2, -0x4(%rbp)
jmp 0x63bd
cmpl $-0x1, -0x20(%rbp)
jne 0x634e
movl $0x1, -0x4(%rbp)
jmp 0x63bd
movl -0x20(%rbp), %eax
movl -0x14(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
je 0x635d
jmp 0x6368
movl -0x14(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x14(%rbp)
jmp 0x6319
movl -0x14(%rbp), %eax
cmpl -0x18(%rbp), %eax
jne 0x6378
movq -0x10(%rbp), %rax
movb $0x2, 0xb(%rax)
jmp 0x63b2
movq -0x10(%rbp), %rax
movzbl 0xb(%rax), %eax
cmpl $0x3, %eax
jne 0x63b0
movl -0x18(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0xc(%rcx), %eax
jb 0x63b0
movl -0x18(%rbp), %eax
movq -0x10(%rbp), %rcx
movl 0xc(%rcx), %ecx
movq -0x10(%rbp), %rdx
addl 0x18(%rdx), %ecx
cmpl %ecx, %eax
ja 0x63b0
movq -0x10(%rbp), %rax
movb $0x2, 0xb(%rax)
jmp 0x63b2
jmp 0x63b4
jmp 0x63b6
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x30, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)