// File: /workspace/github_c_makefile_star2_O3/gadget114514[P]fatfs-example/fatfs/source/ff.c
// Function: follow_path
static
FRESULT follow_path (	/* FR_OK(0): successful, !=0: error code */
	DIR* dp,			/* Directory object to return last directory and found object */
	const TCHAR* path	/* Full-path string to find a file or directory */
)
{
	FRESULT res;
	BYTE ns;
	FATFS *fs = dp->obj.fs;


#if FF_FS_RPATH != 0
	if (*path != '/' && *path != '\\') {	/* Without heading separator */
		dp->obj.sclust = fs->cdir;				/* Start from current directory */
	} else
#endif
	{										/* With heading separator */
		while (*path == '/' || *path == '\\') path++;	/* Strip heading separator */
		dp->obj.sclust = 0;					/* Start from root directory */
	}
#if FF_FS_EXFAT
	dp->obj.n_frag = 0;	/* Invalidate last fragment counter of the object */
#if FF_FS_RPATH != 0
	if (fs->fs_type == FS_EXFAT && dp->obj.sclust) {	/* exFAT: Retrieve the sub-directory's status */
		DIR dj;

		dp->obj.c_scl = fs->cdc_scl;
		dp->obj.c_size = fs->cdc_size;
		dp->obj.c_ofs = fs->cdc_ofs;
		res = load_obj_xdir(&dj, &dp->obj);
		if (res != FR_OK) return res;
		dp->obj.objsize = ld_dword(fs->dirbuf + XDIR_FileSize);
		dp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2;
	}
#endif
#endif

	if ((UINT)*path < ' ') {				/* Null path name is the origin directory itself */
		dp->fn[NSFLAG] = NS_NONAME;
		res = dir_sdi(dp, 0);

	} else {								/* Follow path */
		for (;;) {
			res = create_name(dp, &path);	/* Get a segment name of the path */
			if (res != FR_OK) break;
			res = dir_find(dp);				/* Find an object with the segment name */
			ns = dp->fn[NSFLAG];
			if (res != FR_OK) {				/* Failed to find the object */
				if (res == FR_NO_FILE) {	/* Object is not found */
					if (FF_FS_RPATH && (ns & NS_DOT)) {	/* If dot entry is not exist, stay there */
						if (!(ns & NS_LAST)) continue;	/* Continue to follow if not last segment */
						dp->fn[NSFLAG] = NS_NONAME;
						res = FR_OK;
					} else {							/* Could not find the object */
						if (!(ns & NS_LAST)) res = FR_NO_PATH;	/* Adjust error code if not last segment */
					}
				}
				break;
			}
			if (ns & NS_LAST) break;			/* Last segment matched. Function completed. */
			/* Get into the sub-directory */
			if (!(dp->obj.attr & AM_DIR)) {		/* It is not a sub-directory and cannot follow */
				res = FR_NO_PATH; break;
			}
#if FF_FS_EXFAT
			if (fs->fs_type == FS_EXFAT) {		/* Save containing directory information for next dir */
				dp->obj.c_scl = dp->obj.sclust;
				dp->obj.c_size = ((DWORD)dp->obj.objsize & 0xFFFFFF00) | dp->obj.stat;
				dp->obj.c_ofs = dp->blk_ofs;
				init_alloc_info(fs, &dp->obj);	/* Open next directory */
			} else
#endif
			{
				dp->obj.sclust = ld_clust(fs, fs->win + dp->dptr % SS(fs));	/* Open next directory */
			}
		}
	}

	return res;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r14
movq %rdi, %rbx
movq (%rdi), %rcx
movzbl (%r14), %eax
cmpl $0x5c, %eax
je 0x1b57
cmpl $0x2f, %eax
jne 0x1b5c
incq %r14
jmp 0x1b49
movq $0x0, 0x10(%rbx)
cmpb $0x20, (%r14)
jae 0x1b84
movb $-0x80, 0x4b(%rbx)
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2d33
movq %rcx, -0x30(%rbp)
leaq 0x40(%rbx), %r13
movabsq $0x2020202020202020, %rax # imm = 0x2020202020202020
leaq 0x393b(%rip), %r15      # 0x54d8
movq %rax, (%r13)
movl $0x20202020, 0x7(%r13)  # imm = 0x20202020
movl $0x8, %esi
xorl %edx, %edx
xorl %r9d, %r9d
xorl %ecx, %ecx
leal 0x1(%r9), %r12d
movl %r9d, %eax
movb (%r14,%rax), %r8b
cmpb $0x21, %r8b
jb 0x1dde
leal -0x1(%rsi), %edi
cmpb $0x2e, %r8b
je 0x1cc8
movzbl %r8b, %eax
cmpl $0x5c, %eax
je 0x1cf1
cmpl $0x2f, %eax
je 0x1cf1
cmpl %esi, %ecx
jae 0x1cc8
cmpb $-0x80, %r8b
jbe 0x1c73
cmpb $-0x60, %r8b
setb %r10b
leal 0x20(%r8), %r11d
cmpb $0x1d, %r11b
setb %r11b
orb %r10b, %r11b
cmpb $0x1, %r11b
jne 0x1c73
movl %r12d, %eax
movzbl (%r14,%rax), %r10d
movl $0x6, %eax
cmpl $0x40, %r10d
jb 0x1dff
cmpb $0x7f, %r10b
jb 0x1c50
leal -0xfd(%r10), %r11d
cmpl $0x3, %r11d
jb 0x1dff
cmpl $0x7f, %r10d
je 0x1dff
cmpl %edi, %ecx
jae 0x1dff
addl $0x2, %r9d
movl %ecx, %eax
movb %r8b, 0x40(%rbx,%rax)
movslq %ecx, %rax
addl $0x2, %ecx
movb %r10b, 0x41(%rbx,%rax)
movl %r9d, %r12d
jmp 0x1cae
movq %r15, %r9
movsbl (%r9), %r10d
testl %r10d, %r10d
je 0x1c87
incq %r9
cmpl %eax, %r10d
jne 0x1c76
testb %r10b, %r10b
jne 0x1dfa
leal -0x61(%r8), %r9d
addb $-0x20, %r8b
cmpb $0x1a, %r9b
movzbl %r8b, %r8d
cmovbl %r8d, %eax
movl %ecx, %r8d
incl %ecx
movb %al, (%r13,%r8)
movl %r12d, %r9d
leal 0x1(%r9), %r12d
movl %r9d, %eax
movb (%r14,%rax), %r8b
cmpb $0x21, %r8b
jae 0x1bcd
jmp 0x1d0e
cmpb $0x2e, %r8b
setne %al
orb %al, %dl
movl $0x8, %ecx
movl $0xb, %esi
movl %r12d, %r9d
testb $0x1, %dl
movb $0x1, %dl
je 0x1bb5
jmp 0x1dfa
incl %r12d
movl %r12d, %eax
movzbl (%r14,%rax), %eax
cmpl $0x5c, %eax
je 0x1cee
cmpl $0x2f, %eax
je 0x1cee
xorl %eax, %eax
testl %ecx, %ecx
jne 0x1d10
jmp 0x1dfa
movb $0x4, %al
cmpb $-0x1b, (%r13)
jne 0x1d1c
movb $0x5, (%r13)
movb %al, 0x4b(%rbx)
movq (%rbx), %r15
movq %rbx, %rdi
callq 0x2d33
testl %eax, %eax
jne 0x1dff
movl %r12d, %eax
addq %rax, %r14
movq 0x30(%rbx), %rsi
movq %r15, %rdi
callq 0x1f5d
testl %eax, %eax
jne 0x1de5
movq 0x38(%rbx), %rcx
cmpb $0x0, (%rcx)
je 0x1dea
movb 0xb(%rcx), %al
movl %eax, %edx
andb $0x3f, %dl
movb %dl, 0xa(%rbx)
testb $0x8, 0xb(%rcx)
jne 0x1d87
xorl %edx, %edx
movb (%rcx,%rdx), %sil
movb (%r13,%rdx), %dil
cmpl $0xa, %edx
je 0x1d82
incq %rdx
cmpb %dil, %sil
je 0x1d6c
cmpb %dil, %sil
je 0x1d97
movq %rbx, %rdi
xorl %esi, %esi
callq 0x2fc7
testl %eax, %eax
je 0x1d38
jmp 0x1de5
testb $0x4, 0x4b(%rbx)
jne 0x1e0e
testb $0x10, %al
je 0x1e12
movq 0x20(%rbx), %rcx
andl $0x1ff, %ecx            # imm = 0x1FF
movq -0x30(%rbp), %rdx
movzwl 0x72(%rdx,%rcx), %eax
cmpb $0x3, (%rdx)
jne 0x1dc4
movzwl 0x6c(%rdx,%rcx), %ecx
shll $0x10, %ecx
orq %rcx, %rax
leaq 0x370d(%rip), %r15      # 0x54d8
movq %rax, 0x10(%rbx)
movabsq $0x2020202020202020, %rax # imm = 0x2020202020202020
jmp 0x1b9d
movb $0x4, %al
jmp 0x1d05
cmpl $0x4, %eax
jne 0x1dff
movb 0x4b(%rbx), %cl
andb $0x4, %cl
xorl %eax, %eax
cmpb $0x1, %cl
adcl $0x4, %eax
jmp 0x1dff
movl $0x6, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
xorl %eax, %eax
jmp 0x1dff
movl $0x5, %eax
jmp 0x1dff