// File: /workspace/github_c_makefile_star2_O2/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 %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %r15d
movq %rsi, %r14
movq %rdi, %rbx
movl 0x74(%rdi), %edx
leaq 0x80(%rdi), %r13
leaq 0x88(%rdi), %rcx
xorl %eax, %eax
pushq $-0x1
popq %rbp
xorl %esi, %esi
movl %ebp, %r12d
cmpq %rax, %rdx
je 0x14ff
movl 0x70(%rbx), %r8d
movl %r8d, %edi
subl -0x4(%rcx), %edi
testb $0x2, -0x8(%rcx)
jne 0x14da
movl %eax, %ebp
jmp 0x14df
cmpq %r14, (%rcx)
je 0x1543
testl %r12d, %r12d
sets %r8b
cmpl %esi, %edi
seta %r9b
orb %r8b, %r9b
cmovnel %edi, %esi
cmovnel %eax, %r12d
incq %rax
addq $0x10, %rcx
jmp 0x14c1
testl %ebp, %ebp
jns 0x1519
movq %rbx, %rdi
movl %r12d, %esi
callq 0x1385
movl %r12d, %ebp
testl %eax, %eax
js 0x15b2
testl %r15d, %r15d
je 0x1555
movq (%rbx), %rax
movb (%rax), %cl
movl %ebp, %eax
shll %cl, %eax
leaq (%rbx,%rax), %rdi
addq $0x180, %rdi            # imm = 0x180
pushq $0x1
popq %rax
shll %cl, %eax
movslq %eax, %rdx
xorl %esi, %esi
callq 0x1110
jmp 0x157c
leal 0x1(%r8), %edx
movl %edx, 0x70(%rbx)
movl %r8d, -0x4(%rcx)
incl 0x18(%rbx)
movl %eax, %ebp
jmp 0x15a1
movq (%rbx), %rdi
movb (%rdi), %cl
movl %ebp, %eax
shll %cl, %eax
leaq (%rbx,%rax), %rcx
addq $0x180, %rcx            # imm = 0x180
pushq $0x1
popq %rdx
movq %r14, %rsi
callq *0x8(%rdi)
testl %eax, %eax
js 0x15b7
incl 0x8(%rbx)
incl 0x10(%rbx)
movl %ebp, %eax
shlq $0x4, %rax
movl $0x2, (%r13,%rax)
movq %r14, 0x8(%r13,%rax)
movl 0x70(%rbx), %ecx
leal 0x1(%rcx), %edx
movl %edx, 0x70(%rbx)
movl %ecx, 0x4(%r13,%rax)
incl 0x1c(%rbx)
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
pushq $-0x1
popq %rbp
jmp 0x15a1
movl %ebp, %ecx
shlq $0x4, %rcx
andl $0x0, (%r13,%rcx)
movl %eax, %ebp
jmp 0x15a1