// File: /workspace/github_c_makefile_star2_O3/gadget114514[P]fatfs-example/fatfs/source/ff.c
// Function: f_rename
FRESULT f_rename (
	const TCHAR* path_old,	/* Pointer to the object name to be renamed */
	const TCHAR* path_new	/* Pointer to the new name */
)
{
	FRESULT res;
	DIR djo, djn;
	FATFS *fs;
	BYTE buf[FF_FS_EXFAT ? SZDIRE * 2 : SZDIRE], *dir;
	DWORD dw;
	DEF_NAMBUF


	get_ldnumber(&path_new);						/* Snip the drive number of new name off */
	res = find_volume(&path_old, &fs, FA_WRITE);	/* Get logical drive of the old object */
	if (res == FR_OK) {
		djo.obj.fs = fs;
		INIT_NAMBUF(fs);
		res = follow_path(&djo, path_old);		/* Check old object */
		if (res == FR_OK && (djo.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME;	/* Check validity of name */
#if FF_FS_LOCK != 0
		if (res == FR_OK) {
			res = chk_lock(&djo, 2);
		}
#endif
		if (res == FR_OK) {						/* Object to be renamed is found */
#if FF_FS_EXFAT
			if (fs->fs_type == FS_EXFAT) {	/* At exFAT volume */
				BYTE nf, nn;
				WORD nh;

				mem_cpy(buf, fs->dirbuf, SZDIRE * 2);	/* Save 85+C0 entry of old object */
				mem_cpy(&djn, &djo, sizeof djo);
				res = follow_path(&djn, path_new);		/* Make sure if new object name is not in use */
				if (res == FR_OK) {						/* Is new name already in use by any other object? */
					res = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST;
				}
				if (res == FR_NO_FILE) { 				/* It is a valid path and no name collision */
					res = dir_register(&djn);			/* Register the new entry */
					if (res == FR_OK) {
						nf = fs->dirbuf[XDIR_NumSec]; nn = fs->dirbuf[XDIR_NumName];
						nh = ld_word(fs->dirbuf + XDIR_NameHash);
						mem_cpy(fs->dirbuf, buf, SZDIRE * 2);	/* Restore 85+C0 entry */
						fs->dirbuf[XDIR_NumSec] = nf; fs->dirbuf[XDIR_NumName] = nn;
						st_word(fs->dirbuf + XDIR_NameHash, nh);
						if (!(fs->dirbuf[XDIR_Attr] & AM_DIR)) fs->dirbuf[XDIR_Attr] |= AM_ARC;	/* Set archive attribute if it is a file */
/* Start of critical section where an interruption can cause a cross-link */
						res = store_xdir(&djn);
					}
				}
			} else
#endif
			{	/* At FAT/FAT32 volume */
				mem_cpy(buf, djo.dir, SZDIRE);			/* Save directory entry of the object */
				mem_cpy(&djn, &djo, sizeof (DIR));		/* Duplicate the directory object */
				res = follow_path(&djn, path_new);		/* Make sure if new object name is not in use */
				if (res == FR_OK) {						/* Is new name already in use by any other object? */
					res = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST;
				}
				if (res == FR_NO_FILE) { 				/* It is a valid path and no name collision */
					res = dir_register(&djn);			/* Register the new entry */
					if (res == FR_OK) {
						dir = djn.dir;					/* Copy directory entry of the object except name */
						mem_cpy(dir + 13, buf + 13, SZDIRE - 13);
						dir[DIR_Attr] = buf[DIR_Attr];
						if (!(dir[DIR_Attr] & AM_DIR)) dir[DIR_Attr] |= AM_ARC;	/* Set archive attribute if it is a file */
						fs->wflag = 1;
						if ((dir[DIR_Attr] & AM_DIR) && djo.obj.sclust != djn.obj.sclust) {	/* Update .. entry in the sub-directory if needed */
							dw = clst2sect(fs, ld_clust(fs, dir));
							if (dw == 0) {
								res = FR_INT_ERR;
							} else {
/* Start of critical section where an interruption can cause a cross-link */
								res = move_window(fs, dw);
								dir = fs->win + SZDIRE * 1;	/* Ptr to .. entry */
								if (res == FR_OK && dir[1] == '.') {
									st_clust(fs, dir, djn.obj.sclust);
									fs->wflag = 1;
								}
							}
						}
					}
				}
			}
			if (res == FR_OK) {
				res = dir_remove(&djo);		/* Remove old entry */
				if (res == FR_OK) {
					res = sync_fs(fs);
				}
			}
/* End of the critical section */
		}
		FREE_NAMBUF();
	}

	LEAVE_FF(fs, res);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0xd0, %rsp
movq %rdi, -0x28(%rbp)
testq %rsi, %rsi
je 0x3904
movq %rsi, %r14
xorl %eax, %eax
movb (%r14,%rax), %cl
incq %rax
cmpb $0x21, %cl
jb 0x38e9
cmpb $0x3a, %cl
jne 0x38d8
cmpb $0x3a, %cl
jne 0x3907
leaq (%r14,%rax), %rcx
cmpb $0x30, (%r14)
cmovneq %r14, %rcx
cmpq $0x2, %rax
cmoveq %rcx, %r14
jmp 0x3907
xorl %r14d, %r14d
leaq -0x28(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movl $0x2, %edx
callq 0x144b
testl %eax, %eax
jne 0x3aa4
movq -0x30(%rbp), %rbx
leaq -0xa0(%rbp), %r15
movq %rbx, (%r15)
movq -0x28(%rbp), %rsi
movq %r15, %rdi
callq 0x1b32
movl %eax, %ecx
xorl %edx, %edx
testb $-0x60, 0x4b(%r15)
sete %sil
movl $0x6, %eax
cmovel %edx, %eax
testl %ecx, %ecx
sete %dl
cmovnel %ecx, %eax
andb %sil, %dl
cmpb $0x1, %dl
jne 0x3aa4
leaq -0xa0(%rbp), %rsi
movq 0x38(%rsi), %r15
movb 0xb(%r15), %r12b
movups 0xc(%r15), %xmm0
movaps %xmm0, -0x50(%rbp)
movl 0x1c(%r15), %eax
movl %eax, -0x40(%rbp)
leaq -0xf0(%rbp), %rax
movl $0xa, %ecx
movq %rax, %rdi
rep  movsq (%rsi), %es:(%rdi)
movq %rax, %rdi
movq %r14, %rsi
callq 0x1b32
cmpl $0x4, %eax
je 0x39d7
testl %eax, %eax
jne 0x3aa4
movq -0xe0(%rbp), %rcx
movl $0x8, %eax
cmpq -0x90(%rbp), %rcx
jne 0x3aa4
movq -0x80(%rbp), %rcx
cmpq %rcx, -0xd0(%rbp)
jne 0x3aa4
leaq -0xf0(%rbp), %rdi
callq 0x1e19
testl %eax, %eax
jne 0x3aa4
movq -0xb8(%rbp), %rax
movl -0x40(%rbp), %ecx
movl %ecx, 0x1c(%rax)
movups -0x4f(%rbp), %xmm0
movups %xmm0, 0xd(%rax)
movl %r12d, %ecx
notb %cl
addb %cl, %cl
andb $0x20, %cl
orb %r12b, %cl
movb %cl, 0xb(%rax)
movb $0x1, 0x3(%rbx)
testb $0x10, 0xb(%rax)
je 0x3a2a
movq -0xe0(%rbp), %r14
cmpq %r14, -0x90(%rbp)
jne 0x3a61
movq -0xa0(%rbp), %r14
movq -0x70(%rbp), %rsi
movq %r14, %rdi
callq 0x1f5d
testl %eax, %eax
jne 0x3aa4
movb $-0x1b, (%r15)
movb $0x1, 0x3(%r14)
movq %rbx, %rdi
addq $0xd0, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2952
movzwl 0x1a(%rax), %esi
cmpb $0x3, (%rbx)
jne 0x3a74
movzwl 0x14(%rax), %eax
shll $0x10, %eax
orq %rax, %rsi
addq $-0x2, %rsi
movq 0x20(%rbx), %rcx
addq $-0x2, %rcx
movl $0x2, %eax
cmpq %rcx, %rsi
jae 0x3aa4
movzwl 0xa(%rbx), %ecx
imulq %rcx, %rsi
addq 0x48(%rbx), %rsi
je 0x3aa4
movq %rbx, %rdi
callq 0x1f5d
testl %eax, %eax
je 0x3ab4
addq $0xd0, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
cmpb $0x2e, 0x79(%rbx)
jne 0x3a2a
movw %r14w, 0x92(%rbx)
cmpb $0x3, (%rbx)
jne 0x3ae2
movl %r14d, %eax
shrl $0x10, %eax
movb %al, 0x8c(%rbx)
shrl $0x18, %r14d
movb %r14b, 0x8d(%rbx)
movb $0x1, 0x3(%rbx)
jmp 0x3a2a