// File: /workspace/github_c_makefile_star2_O0/dlbeer[P]ufat/ufat.c
// Function: parse_bpb
static int parse_bpb(unsigned int log2_bytes_per_block,
		     struct ufat_bpb *ufb, uint8_t *bpb)
{
	const uint16_t bytes_per_sector = r16(bpb + 0x00b);
	const uint8_t sectors_per_cluster = bpb[0x00d];
	const uint16_t reserved_sector_count = r16(bpb + 0x00e);
	const uint16_t root_entries = r16(bpb + 0x011);
	uint32_t sectors_per_fat = r16(bpb + 0x016);
	uint32_t total_logical_sectors = r16(bpb + 0x013);
	const uint8_t number_of_fats = bpb[0x010];
	const uint32_t root_cluster = r32(bpb + 0x02c);
	unsigned int log2_bytes_per_sector = 0;
	unsigned int log2_sectors_per_cluster = 0;
	const unsigned int root_sectors =
		(root_entries * UFAT_DIRENT_SIZE + bytes_per_sector - 1) /
		bytes_per_sector;

	/* Read and check BPB values */
	if (log2_bytes_per_block < 9)
		return -UFAT_ERR_BLOCK_SIZE;

	if (!total_logical_sectors)
		total_logical_sectors = r32(bpb + 0x020);
	if (!sectors_per_fat)
		sectors_per_fat = r32(bpb + 0x024);

	if (log2_exact(bytes_per_sector, &log2_bytes_per_sector) < 0 ||
	    log2_exact(sectors_per_cluster, &log2_sectors_per_cluster) < 0)
		return -UFAT_ERR_INVALID_BPB;

	if (r16(bpb + 0x1fe) != 0xaa55)
		return -UFAT_ERR_INVALID_BPB;

	/* Convert sectors to blocks */
	if (log2_bytes_per_block > log2_bytes_per_sector) {
		const unsigned int shift =
			log2_bytes_per_block - log2_bytes_per_sector;

		if (log2_sectors_per_cluster < shift)
			return -UFAT_ERR_BLOCK_ALIGNMENT;
		ufb->log2_blocks_per_cluster =
			log2_sectors_per_cluster - shift;

		if ((reserved_sector_count | sectors_per_fat | root_sectors) &
		    ((1 << shift) - 1))
			return -UFAT_ERR_BLOCK_ALIGNMENT;
		ufb->fat_start = reserved_sector_count >> shift;
		ufb->fat_size = sectors_per_fat >> shift;
		ufb->root_size = root_sectors >> shift;
	} else {
		const unsigned int shift =
			log2_bytes_per_sector - log2_bytes_per_block;

		ufb->log2_blocks_per_cluster =
			log2_sectors_per_cluster + shift;
		ufb->fat_start = reserved_sector_count << shift;
		ufb->fat_size = sectors_per_fat << shift;
		ufb->root_size = root_sectors << shift;
	}

	if (!number_of_fats)
		return -UFAT_ERR_INVALID_BPB;

	/* Various block-size independent values */
	ufb->fat_count = number_of_fats;
	ufb->num_clusters =
		((total_logical_sectors - reserved_sector_count -
		  sectors_per_fat * number_of_fats -
		  root_sectors) >>
		 log2_sectors_per_cluster) + 2;
	ufb->root_cluster = root_cluster & UFAT_CLUSTER_MASK;
	ufb->root_start = ufb->fat_start + ufb->fat_size * ufb->fat_count;
	ufb->cluster_start = ufb->root_start + ufb->root_size;

	/* Figure out filesystem type */
	if (!root_sectors) {
		ufb->type = UFAT_TYPE_FAT32;
	} else {
		ufb->root_cluster = 0;
		if (ufb->num_clusters <= UFAT_MAX_FAT12)
			ufb->type = UFAT_TYPE_FAT12;
		else
			ufb->type = UFAT_TYPE_FAT16;
	}

	return 0;
}

// Assembly:
subq $0x48, %rsp
movl %edi, 0x40(%rsp)
movq %rsi, 0x38(%rsp)
movq %rdx, 0x30(%rsp)
movq 0x30(%rsp), %rdi
addq $0xb, %rdi
callq 0x38f0
movw %ax, 0x2e(%rsp)
movq 0x30(%rsp), %rax
movb 0xd(%rax), %al
movb %al, 0x2d(%rsp)
movq 0x30(%rsp), %rdi
addq $0xe, %rdi
callq 0x38f0
movw %ax, 0x2a(%rsp)
movq 0x30(%rsp), %rdi
addq $0x11, %rdi
callq 0x38f0
movw %ax, 0x28(%rsp)
movq 0x30(%rsp), %rdi
addq $0x16, %rdi
callq 0x38f0
movzwl %ax, %eax
movl %eax, 0x24(%rsp)
movq 0x30(%rsp), %rdi
addq $0x13, %rdi
callq 0x38f0
movzwl %ax, %eax
movl %eax, 0x20(%rsp)
movq 0x30(%rsp), %rax
movb 0x10(%rax), %al
movb %al, 0x1f(%rsp)
movq 0x30(%rsp), %rdi
addq $0x2c, %rdi
callq 0x3920
movl %eax, 0x18(%rsp)
movl $0x0, 0x14(%rsp)
movl $0x0, 0x10(%rsp)
movzwl 0x28(%rsp), %eax
shll $0x5, %eax
movzwl 0x2e(%rsp), %ecx
addl %ecx, %eax
subl $0x1, %eax
movzwl 0x2e(%rsp), %ecx
cltd
idivl %ecx
movl %eax, 0xc(%rsp)
cmpl $0x9, 0x40(%rsp)
jae 0x3641
movl $0xfffffffe, 0x44(%rsp) # imm = 0xFFFFFFFE
jmp 0x38e2
cmpl $0x0, 0x20(%rsp)
jne 0x365a
movq 0x30(%rsp), %rdi
addq $0x20, %rdi
callq 0x3920
movl %eax, 0x20(%rsp)
cmpl $0x0, 0x24(%rsp)
jne 0x3673
movq 0x30(%rsp), %rdi
addq $0x24, %rdi
callq 0x3920
movl %eax, 0x24(%rsp)
movzwl 0x2e(%rsp), %edi
leaq 0x14(%rsp), %rsi
callq 0x3960
cmpl $0x0, %eax
jl 0x369b
movzbl 0x2d(%rsp), %edi
leaq 0x10(%rsp), %rsi
callq 0x3960
cmpl $0x0, %eax
jge 0x36a8
movl $0xfffffffd, 0x44(%rsp) # imm = 0xFFFFFFFD
jmp 0x38e2
movq 0x30(%rsp), %rdi
addq $0x1fe, %rdi            # imm = 0x1FE
callq 0x38f0
movzwl %ax, %eax
cmpl $0xaa55, %eax           # imm = 0xAA55
je 0x36d0
movl $0xfffffffd, 0x44(%rsp) # imm = 0xFFFFFFFD
jmp 0x38e2
movl 0x40(%rsp), %eax
cmpl 0x14(%rsp), %eax
jbe 0x3789
movl 0x40(%rsp), %eax
subl 0x14(%rsp), %eax
movl %eax, 0x8(%rsp)
movl 0x10(%rsp), %eax
cmpl 0x8(%rsp), %eax
jae 0x3701
movl $0xfffffffc, 0x44(%rsp) # imm = 0xFFFFFFFC
jmp 0x38e2
movl 0x10(%rsp), %ecx
subl 0x8(%rsp), %ecx
movq 0x38(%rsp), %rax
movl %ecx, 0x4(%rax)
movzwl 0x2a(%rsp), %eax
orl 0x24(%rsp), %eax
orl 0xc(%rsp), %eax
movl 0x8(%rsp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
subl $0x1, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
je 0x3742
movl $0xfffffffc, 0x44(%rsp) # imm = 0xFFFFFFFC
jmp 0x38e2
movzwl 0x2a(%rsp), %eax
movl 0x8(%rsp), %ecx
sarl %cl, %eax
movslq %eax, %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x8(%rax)
movl 0x24(%rsp), %eax
movl 0x8(%rsp), %ecx
shrl %cl, %eax
movl %eax, %eax
movl %eax, %ecx
movq 0x38(%rsp), %rax
movq %rcx, 0x10(%rax)
movl 0xc(%rsp), %eax
movl 0x8(%rsp), %ecx
shrl %cl, %eax
movl %eax, %eax
movl %eax, %ecx
movq 0x38(%rsp), %rax
movq %rcx, 0x38(%rax)
jmp 0x37ea
movl 0x14(%rsp), %eax
subl 0x40(%rsp), %eax
movl %eax, 0x4(%rsp)
movl 0x10(%rsp), %ecx
addl 0x4(%rsp), %ecx
movq 0x38(%rsp), %rax
movl %ecx, 0x4(%rax)
movzwl 0x2a(%rsp), %eax
movl 0x4(%rsp), %ecx
shll %cl, %eax
movslq %eax, %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x8(%rax)
movl 0x24(%rsp), %eax
movl 0x4(%rsp), %ecx
shll %cl, %eax
movl %eax, %eax
movl %eax, %ecx
movq 0x38(%rsp), %rax
movq %rcx, 0x10(%rax)
movl 0xc(%rsp), %eax
movl 0x4(%rsp), %ecx
shll %cl, %eax
movl %eax, %eax
movl %eax, %ecx
movq 0x38(%rsp), %rax
movq %rcx, 0x38(%rax)
cmpb $0x0, 0x1f(%rsp)
jne 0x37fe
movl $0xfffffffd, 0x44(%rsp) # imm = 0xFFFFFFFD
jmp 0x38e2
movzbl 0x1f(%rsp), %ecx
movq 0x38(%rsp), %rax
movl %ecx, 0x18(%rax)
movl 0x20(%rsp), %eax
movzwl 0x2a(%rsp), %ecx
subl %ecx, %eax
movl 0x24(%rsp), %ecx
movzbl 0x1f(%rsp), %edx
imull %edx, %ecx
subl %ecx, %eax
subl 0xc(%rsp), %eax
movl 0x10(%rsp), %ecx
shrl %cl, %eax
movl %eax, %ecx
addl $0x2, %ecx
movq 0x38(%rsp), %rax
movl %ecx, 0x28(%rax)
movl 0x18(%rsp), %ecx
andl $0xfffffff, %ecx        # imm = 0xFFFFFFF
movq 0x38(%rsp), %rax
movl %ecx, 0x40(%rax)
movq 0x38(%rsp), %rax
movq 0x8(%rax), %rcx
movq 0x38(%rsp), %rax
movq 0x10(%rax), %rax
movq 0x38(%rsp), %rdx
movl 0x18(%rdx), %edx
imulq %rdx, %rax
addq %rax, %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x30(%rax)
movq 0x38(%rsp), %rax
movq 0x30(%rax), %rcx
movq 0x38(%rsp), %rax
addq 0x38(%rax), %rcx
movq 0x38(%rsp), %rax
movq %rcx, 0x20(%rax)
cmpl $0x0, 0xc(%rsp)
jne 0x38a6
movq 0x38(%rsp), %rax
movl $0x20, (%rax)
jmp 0x38da
movq 0x38(%rsp), %rax
movl $0x0, 0x40(%rax)
movq 0x38(%rsp), %rax
cmpl $0xff6, 0x28(%rax)      # imm = 0xFF6
ja 0x38cd
movq 0x38(%rsp), %rax
movl $0xc, (%rax)
jmp 0x38d8
movq 0x38(%rsp), %rax
movl $0x10, (%rax)
jmp 0x38da
movl $0x0, 0x44(%rsp)
movl 0x44(%rsp), %eax
addq $0x48, %rsp
retq
nopl (%rax,%rax)