// File: /workspace/github_c_makefile_star2_O0/dlbeer[P]ufat/ufat_file.c
// Function: write_blocks
static int write_blocks(struct ufat_file *f, const char *buf, ufat_size_t size)
{
	struct ufat *uf = f->uf;
	const struct ufat_bpb *bpb = &uf->bpb;
	const unsigned int log2_block_size = uf->dev->log2_block_size;
	const unsigned int blocks_per_cluster =
		1 << bpb->log2_blocks_per_cluster;
	const unsigned int block_offset =
		(f->cur_pos >> log2_block_size) & (blocks_per_cluster - 1);
	const unsigned int block_remainder =
		blocks_per_cluster - block_offset;
	ufat_block_t starting_block;
	unsigned int requested_blocks = size >> log2_block_size;
	int i;

	if (requested_blocks > block_remainder)
		requested_blocks = block_remainder;
	if (!requested_blocks)
		return 0;

	i = ensure_room(f);
	if (i < 0)
		return i;

	/* We're writing contiguous whole blocks, so we can bypass the
	 * cache and perform a single large write.
	 */
	starting_block = cluster_to_block(bpb, f->cur_cluster) + block_offset;
	ufat_cache_invalidate(uf, starting_block, requested_blocks);

	i = uf->dev->write(uf->dev, starting_block, requested_blocks, buf);
	if (i < 0)
		return -UFAT_ERR_IO;

	uf->stat.write++;
	uf->stat.write_blocks += requested_blocks;

	i = advance_ptr(f, requested_blocks << log2_block_size);
	if (i < 0)
		return i;

	return requested_blocks << log2_block_size;
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x48(%rsp)
movq %rsi, 0x40(%rsp)
movl %edx, 0x3c(%rsp)
movq 0x48(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x30(%rsp)
movq 0x30(%rsp), %rax
addq $0x28, %rax
movq %rax, 0x28(%rsp)
movq 0x30(%rsp), %rax
movq (%rax), %rax
movl (%rax), %eax
movl %eax, 0x24(%rsp)
movq 0x28(%rsp), %rax
movl 0x4(%rax), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, 0x20(%rsp)
movq 0x48(%rsp), %rax
movl 0x24(%rax), %eax
movl 0x24(%rsp), %ecx
shrl %cl, %eax
movl 0x20(%rsp), %ecx
subl $0x1, %ecx
andl %ecx, %eax
movl %eax, 0x1c(%rsp)
movl 0x20(%rsp), %eax
subl 0x1c(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x3c(%rsp), %eax
movl 0x24(%rsp), %ecx
shrl %cl, %eax
movl %eax, 0xc(%rsp)
movl 0xc(%rsp), %eax
cmpl 0x18(%rsp), %eax
jbe 0x5925
movl 0x18(%rsp), %eax
movl %eax, 0xc(%rsp)
cmpl $0x0, 0xc(%rsp)
jne 0x5939
movl $0x0, 0x54(%rsp)
jmp 0x5a1d
movq 0x48(%rsp), %rdi
callq 0x5e20
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
jge 0x595b
movl 0x8(%rsp), %eax
movl %eax, 0x54(%rsp)
jmp 0x5a1d
movq 0x28(%rsp), %rdi
movq 0x48(%rsp), %rax
movl 0x20(%rax), %esi
callq 0x5dc0
movl 0x1c(%rsp), %ecx
addq %rcx, %rax
movq %rax, 0x10(%rsp)
movq 0x30(%rsp), %rdi
movq 0x10(%rsp), %rsi
movl 0xc(%rsp), %eax
movl %eax, %edx
callq 0x25c0
movq 0x30(%rsp), %rax
movq (%rax), %rax
movq 0x10(%rax), %rax
movq 0x30(%rsp), %rcx
movq (%rcx), %rdi
movq 0x10(%rsp), %rsi
movl 0xc(%rsp), %ecx
movl %ecx, %edx
movq 0x40(%rsp), %rcx
callq *%rax
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
jge 0x59c9
movl $0xffffffff, 0x54(%rsp) # imm = 0xFFFFFFFF
jmp 0x5a1d
movq 0x30(%rsp), %rax
movl 0xc(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xc(%rax)
movl 0xc(%rsp), %ecx
movq 0x30(%rsp), %rax
addl 0x14(%rax), %ecx
movl %ecx, 0x14(%rax)
movq 0x48(%rsp), %rdi
movl 0xc(%rsp), %esi
movl 0x24(%rsp), %ecx
shll %cl, %esi
callq 0x5030
movl %eax, 0x8(%rsp)
cmpl $0x0, 0x8(%rsp)
jge 0x5a0f
movl 0x8(%rsp), %eax
movl %eax, 0x54(%rsp)
jmp 0x5a1d
movl 0xc(%rsp), %eax
movl 0x24(%rsp), %ecx
shll %cl, %eax
movl %eax, 0x54(%rsp)
movl 0x54(%rsp), %eax
addq $0x58, %rsp
retq
nopw %cs:(%rax,%rax)