// File: /workspace/github_c_makefile_star2_O1/dlbeer[P]ufat/ufat.c
// Function: ufat_cache_open
int ufat_cache_open(struct ufat *uf, ufat_block_t blk_index, int skip_read)
{
	unsigned int i;
	int oldest = -1;
	int free = -1;
	int err;
	unsigned int oldest_age = 0;

	/* Scan the cache, looking for:
	 *
	 *   (a) the item, if we already have it.
	 *   (b) a free slot, if one exists.
	 *   (c) the oldest cache item.
	 */
	for (i = 0; i < uf->cache_size; i++) {
		struct ufat_cache_desc *d = &uf->cache_desc[i];
		unsigned int age = uf->next_seq - d->seq;

		if ((d->flags & UFAT_CACHE_FLAG_PRESENT) &&
		    d->index == blk_index) {
			d->seq = uf->next_seq++;
			uf->stat.cache_hit++;
			return i;
		}

		if (!(d->flags & UFAT_CACHE_FLAG_PRESENT))
			free = i;

		if (oldest < 0 || age > oldest_age) {
			oldest_age = age;
			oldest = i;
		}
	}

	/* We don't have the item. Find a place to put it. */
	if (free >= 0) {
		i = free;
	} else {
		err = cache_flush(uf, oldest);
		if (err < 0)
			return err;

		i = oldest;
	}

	if (skip_read == 0) {
		/* Read it in */
		err = uf->dev->read(uf->dev, blk_index, 1,
				    ufat_cache_data(uf, i));
		if (err < 0) {
			uf->cache_desc[i].flags = 0;
			return err;
		}

		uf->stat.read++;
		uf->stat.read_blocks++;
	} else
		memset(ufat_cache_data(uf, i), 0,
		       1 << uf->dev->log2_block_size);

	struct ufat_cache_desc *d = &uf->cache_desc[i];
	d->flags = UFAT_CACHE_FLAG_PRESENT;
	d->index = blk_index;
	d->seq = uf->next_seq++;

	uf->stat.cache_miss++;

	return i;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %edx, %r15d
movq %rsi, %r14
movq %rdi, %rbx
movl 0x74(%rdi), %eax
testq %rax, %rax
je 0x1b69
movl 0x70(%rbx), %edi
leaq 0x88(%rbx), %rcx
xorl %edx, %edx
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
xorl %r8d, %r8d
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl %edi, %r9d
subl -0x4(%rcx), %r9d
testb $0x2, -0x8(%rcx)
jne 0x1b19
movl %edx, %esi
jmp 0x1b36
cmpq %r14, (%rcx)
jne 0x1b36
leal 0x1(%rdi), %r10d
movl %r10d, 0x70(%rbx)
movl %edi, -0x4(%rcx)
incl 0x18(%rbx)
xorl %r9d, %r9d
movl %r10d, %edi
movl %edx, %ebp
jmp 0x1b52
testl %r12d, %r12d
sets %r10b
cmpl %r8d, %r9d
seta %r11b
orb %r10b, %r11b
cmovnel %r9d, %r8d
cmovnel %edx, %r12d
movb $0x1, %r9b
testb %r9b, %r9b
je 0x1c11
incq %rdx
addq $0x10, %rcx
cmpq %rdx, %rax
jne 0x1b08
jmp 0x1b74
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl $0xffffffff, %r12d      # imm = 0xFFFFFFFF
movl %esi, %ebp
testl %esi, %esi
jns 0x1b90
movq %rbx, %rdi
movl %r12d, %esi
callq 0x19a9
movl %r12d, %ebp
testl %eax, %eax
js 0x1c1c
testl %r15d, %r15d
je 0x1bbc
movq (%rbx), %rax
movb (%rax), %cl
movl %ebp, %eax
shll %cl, %eax
leaq (%rbx,%rax), %rdi
addq $0x180, %rdi            # imm = 0x180
movl $0x1, %eax
shll %cl, %eax
movslq %eax, %rdx
xorl %esi, %esi
callq 0x1110
jmp 0x1be5
movq (%rbx), %rdi
movb (%rdi), %cl
movl %ebp, %eax
shll %cl, %eax
leaq (%rbx,%rax), %rcx
addq $0x180, %rcx            # imm = 0x180
movl $0x1, %edx
movq %r14, %rsi
callq *0x8(%rdi)
testl %eax, %eax
js 0x1c23
incl 0x8(%rbx)
incl 0x10(%rbx)
movl %ebp, %eax
shlq $0x4, %rax
movl $0x2, 0x80(%rbx,%rax)
movq %r14, 0x88(%rbx,%rax)
movl 0x70(%rbx), %ecx
leal 0x1(%rcx), %edx
movl %edx, 0x70(%rbx)
movl %ecx, 0x84(%rbx,%rax)
incl 0x1c(%rbx)
movl %ebp, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
jmp 0x1c11
movl %ebp, %ecx
shlq $0x4, %rcx
movl $0x0, 0x80(%rbx,%rcx)
movl %eax, %ebp
jmp 0x1c11