// File: /workspace/github_c_makefile_star2_O0/cogbee[P]vmir-latest/tlsf/tlsf.c
// Function: tlsf_memalign
void* tlsf_memalign(tlsf_pool tlsf, size_t align, size_t size)
{
	pool_t* pool = tlsf_cast(pool_t*, tlsf);
	const size_t adjust = adjust_request_size(size, ALIGN_SIZE);

	/*
	** We must allocate an additional minimum block size bytes so that if
	** our free block will leave an alignment gap which is smaller, we can
	** trim a leading free block and release it back to the heap. We must
	** do this because the previous physical block is in use, therefore
	** the prev_phys_block field is not valid, and we can't simply adjust
	** the size of that block.
	*/
	const size_t gap_minimum = sizeof(block_header_t);
	const size_t size_with_gap = adjust_request_size(adjust + align + gap_minimum, align);

	/* If alignment is less than or equals base alignment, we're done. */
	const size_t aligned_size = (align <= ALIGN_SIZE) ? adjust : size_with_gap;

	block_header_t* block = block_locate_free(pool, aligned_size);

	/* This can't be a static assert. */
	tlsf_assert(sizeof(block_header_t) == block_size_min + block_header_overhead);

	if (block)
	{
		void* ptr = block_to_ptr(block);
		void* aligned = align_ptr(ptr, align);
		size_t gap = tlsf_cast(size_t,
			tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr));

		/* If gap size is too small, offset to next aligned boundary. */
		if (gap && gap < gap_minimum)
		{
			const size_t gap_remain = gap_minimum - gap;
			const size_t offset = tlsf_max(gap_remain, align);
			const void* next_aligned = tlsf_cast(void*,
				tlsf_cast(tlsfptr_t, aligned) + offset);

			aligned = align_ptr(next_aligned, align);
			gap = tlsf_cast(size_t,
				tlsf_cast(tlsfptr_t, aligned) - tlsf_cast(tlsfptr_t, ptr));
		}

		if (gap)
		{
			tlsf_assert(gap >= gap_minimum && "gap size too small");
			block = block_trim_free_leading(pool, block, gap);
		}
	}

	return block_prepare_used(pool, block, adjust);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rdi
movl $0x8, %esi
callq 0x3a1e0
movq %rax, -0x28(%rbp)
movq $0x20, -0x30(%rbp)
movq -0x28(%rbp), %rdi
addq -0x10(%rbp), %rdi
addq $0x20, %rdi
movq -0x10(%rbp), %rsi
callq 0x3a1e0
movq %rax, -0x38(%rbp)
cmpq $0x8, -0x10(%rbp)
ja 0x3a3c3
movq -0x28(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0x3a3cb
movq -0x38(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x3a250
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x3a4de
movq -0x48(%rbp), %rdi
callq 0x39d90
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x3a500
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq -0x50(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
je 0x3a490
cmpq $0x20, -0x60(%rbp)
jae 0x3a490
movl $0x20, %eax
subq -0x60(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
cmpq -0x10(%rbp), %rax
jbe 0x3a44e
movq -0x68(%rbp), %rax
movq %rax, -0x88(%rbp)
jmp 0x3a459
movq -0x10(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x58(%rbp), %rax
addq -0x70(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x3a500
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq -0x50(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x60(%rbp)
cmpq $0x0, -0x60(%rbp)
je 0x3a4dc
cmpq $0x20, -0x60(%rbp)
jb 0x3a4a8
movb $0x1, %al
testb $0x1, %al
jne 0x3a4a6
jmp 0x3a4a8
jmp 0x3a4c7
leaq 0x7397(%rip), %rdi      # 0x41846
leaq 0x7055(%rip), %rsi      # 0x4150b
movl $0x37a, %edx            # imm = 0x37A
leaq 0x73af(%rip), %rcx      # 0x41871
callq 0x31c0
movq -0x20(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x60(%rbp), %rdx
callq 0x3a580
movq %rax, -0x48(%rbp)
jmp 0x3a4de
movq -0x20(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x3a300
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax,%rax)