// File: /workspace/github_c_makefile_star2_O3/j-hoppe[P]tu58fs/rt11.c
// Function: rt11_filesystem_calc_block_use
static int rt11_filesystem_calc_block_use(rt11_filesystem_t *_this, int test_data_size) {
	int i;
	int dir_max_seg_nr;
	int used_file_blocks;
	int available_blocks;

	if (_this->dir_entry_extra_bytes > 16)
		fatal("Extra bytes in directory %d is > 16 ... how much is allowed?", _this->dir_entry_extra_bytes);

	// 1) calc segments & blocks needed for existing files
	used_file_blocks = 0;
	for (i = 0; i < _this->file_count; i++) {
		// round file sizes up to blocks
		// prefix size and data size already sum'd up to file->block_count
		used_file_blocks += _this->file[i]->block_count;
	}
	if (test_data_size)
		used_file_blocks += NEEDED_BLOCKS(RT11_BLOCKSIZE, test_data_size);

	// total blocks available for dir and data
	// On disk supporting STd144 bad secotr info,
	// "available blocks" should not be calculated from total disk size,
	// but from usable blockcount of "rt11_radi".
	// Difficulties in case of enlarged images!
	available_blocks = _this->blockcount - _this->first_dir_blocknr; // boot, home, 2..5 used
	if (test_data_size)
		dir_max_seg_nr = rt11_dir_needed_segments(_this, _this->file_count + 1);
	else
		dir_max_seg_nr = rt11_dir_needed_segments(_this, _this->file_count);
	if (available_blocks < used_file_blocks + 2 * dir_max_seg_nr) {
		// files do not fit on volume
		if (!test_data_size)
			_this->free_blocks = 0; // can't be negative
		return error_set(ERROR_FILESYSTEM_OVERFLOW, "rt11_filesystem_calc_block_use");
	}
	if (test_data_size)
		return ERROR_OK;

	/* end of test mode */
	// now modify file system
	_this->dir_max_seg_nr = dir_max_seg_nr;
	_this->used_file_blocks = used_file_blocks;

	_this->free_blocks = available_blocks - _this->used_file_blocks - 2 * _this->dir_max_seg_nr;
	// now used_blocks,free_blocks, dir_total_seg_num valid.

	/* Plan use of remaining free_space
	 * how many files would be allocated in the remaining free space?
	 * derive from average file size, but allow 1.5 * as much
	 * Most critical test situations:
	 * All dir segments full, and only 2 block in file area left.
	 * assigned these blocks to 1 more file would need a new dir segment,
	 * which would need these 2 blocks too.
	 * If 3 blocks are left: 2 can be used for additional dir segmetn,
	 * and 1 for new file.
	 */
	if (_this->file_count == 0) {
		// if disk empty: start with only 1 segment
		_this->dir_max_seg_nr = 1;
		_this->dir_total_seg_num = 1;
	} else {
		// planning params have prefix "_"
		int avg_file_blocks; // average filesize in blocks
		int _new_file_count; // planned count of additional files
		int _used_file_blocks; // planned block requirement for all files (existing + planned)
		int _dir_total_seg_num; // planned dir segment requirement for all files (existing + planned)
		avg_file_blocks = _this->used_file_blocks / _this->file_count;
		if (avg_file_blocks < 1)
			avg_file_blocks = 1;
		// 1st estimate for possible new files.
		// Assume they have average size.
		// too big, since additional dir segments reduce free space
		_new_file_count = _this->free_blocks / avg_file_blocks + 1;
		// reduce amount of planned files, until files+dir fit on disk
		do {
			_new_file_count--;
			_used_file_blocks = _this->used_file_blocks + _new_file_count * avg_file_blocks;
			// plan for 50% more file count
			_dir_total_seg_num = rt11_dir_needed_segments(_this,
					_this->file_count + (_new_file_count * 3) / 2);
		} while (_new_file_count
				&& available_blocks < _used_file_blocks + 2 * _dir_total_seg_num);
		// solution found: save
		if (_dir_total_seg_num > 31)
			_dir_total_seg_num = 31;
		_this->dir_total_seg_num = _dir_total_seg_num;
	}
	// calculate free blocks again
	assert(available_blocks >= _this->used_file_blocks + 2 * _this->dir_total_seg_num);
	_this->free_blocks = available_blocks - _this->used_file_blocks
			- 2 * _this->dir_total_seg_num;

	return ERROR_OK;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movl %esi, %r14d
movq %rdi, %rbx
movzwl 0x68(%rdi), %esi
cmpl $0x11, %esi
jb 0xfc43
leaq 0x7076(%rip), %rdi      # 0x16cb2
xorl %eax, %eax
callq 0xa2d7
movslq 0x8c(%rbx), %rdi
testq %rdi, %rdi
jle 0xfc6d
xorl %eax, %eax
xorl %r9d, %r9d
movq 0x90(%rbx,%rax,8), %rcx
movzwl 0x7c(%rcx), %ecx
addl %ecx, %r9d
incq %rax
cmpq %rax, %rdi
jne 0xfc54
jmp 0xfc70
xorl %r9d, %r9d
testl %r14d, %r14d
je 0xfcc6
leal 0x1ff(%r14), %eax
addl $0x3fe, %r14d           # imm = 0x3FE
testl %eax, %eax
cmovnsl %eax, %r14d
sarl $0x9, %r14d
addl %r14d, %r9d
movl 0x6c(%rbx), %esi
movzwl 0x34(%rbx), %eax
subl %eax, %esi
movzwl 0x68(%rbx), %ecx
addl $0xe, %ecx
movl $0x3f6, %eax            # imm = 0x3F6
xorl %edx, %edx
divl %ecx
leal (%rdi,%rax), %ecx
addl $-0x2, %ecx
movl %eax, %edi
addl $-0x3, %edi
movl %ecx, %eax
cltd
idivl %edi
leal (%r9,%rax,2), %eax
cmpl %eax, %esi
jl 0xfd08
jmp 0xfdbd
movl 0x6c(%rbx), %r8d
movzwl 0x34(%rbx), %eax
subl %eax, %r8d
movzwl 0x68(%rbx), %ecx
addl $0xe, %ecx
movl $0x3f6, %eax            # imm = 0x3F6
xorl %edx, %edx
divl %ecx
leal (%rax,%rdi), %ecx
addl $-0x3, %ecx
movl %eax, %r10d
addl $-0x3, %r10d
movl %ecx, %eax
cltd
idivl %r10d
leal (%r9,%rax,2), %ecx
movl %r8d, %esi
subl %ecx, %esi
jge 0xfd22
movw $0x0, 0x1fd2(%rbx)
leaq 0x6fe0(%rip), %rsi      # 0x16cef
movl $0xfffffffe, %edi       # imm = 0xFFFFFFFE
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x9f73
movw %ax, 0x66(%rbx)
movw %r9w, 0x1fd0(%rbx)
movw %si, 0x1fd2(%rbx)
testl %edi, %edi
je 0xfd9e
movzwl %r9w, %ecx
movl %ecx, %eax
xorl %edx, %edx
idivl %edi
cmpl $0x2, %eax
movl $0x1, %r9d
cmovgel %eax, %r9d
movl %esi, %eax
xorl %edx, %edx
divw %r9w
movzwl %ax, %esi
incl %esi
addl %r10d, %edi
decl %esi
leal (%rsi,%rsi,2), %edx
movl %edx, %eax
shrl $0x1f, %eax
addl %edx, %eax
sarl %eax
addl %edi, %eax
cltd
idivl %r10d
testl %esi, %esi
je 0xfd88
movl %esi, %edx
imull %r9d, %edx
addl %ecx, %edx
leal (%rdx,%rax,2), %edx
cmpl %edx, %r8d
jl 0xfd60
cmpl $0x1f, %eax
movl $0x1f, %edx
cmovll %eax, %edx
movw %dx, 0x64(%rbx)
movzwl %dx, %eax
addl %eax, %eax
jmp 0xfdae
movl $0x10001, 0x64(%rbx)    # imm = 0x10001
movzwl %r9w, %ecx
movl $0x2, %eax
addl %eax, %ecx
subl %ecx, %r8d
jl 0xfdc7
movw %r8w, 0x1fd2(%rbx)
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x6f40(%rip), %rdi      # 0x16d0e
leaq 0x69ab(%rip), %rsi      # 0x16780
leaq 0x6f7d(%rip), %rcx      # 0x16d59
movl $0x1c9, %edx            # imm = 0x1C9
callq 0x3200