// File: /workspace/github_c_makefile_star2_O2/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 %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rsi, %r12
movq %rdi, %rbx
leaq -0x1(%rdx), %rax
movl $0xfffffffe, %ecx       # imm = 0xFFFFFFFE
cmpq %rcx, %rax
ja 0x1d310
addq $0x7, %rdx
movabsq $0x1fffffff8, %rax      # imm = 0x1FFFFFFF8
andq %rdx, %rax
cmpq $0x19, %rax
pushq $0x18
popq %r14
cmovaeq %rax, %r14
jmp 0x1d313
xorl %r14d, %r14d
leaq (%r12,%r14), %rdi
addq $0x20, %rdi
movq %r12, %rsi
callq 0x1d0fe
cmpq $0x9, %r12
cmovbq %r14, %rax
movq %rbx, %rdi
movq %rax, %rsi
callq 0x1d14c
testq %rax, %rax
je 0x1d3c6
movq %rax, %r15
leaq 0x10(%rax), %r13
movq %r13, %rdi
movq %r12, %rsi
callq 0x1d3ff
movq %rax, %rcx
subq %r13, %rax
leaq -0x1(%rax), %rdx
cmpq $0x1e, %rdx
ja 0x1d37c
pushq $0x20
popq %rdi
subq %rax, %rdi
cmpq %r12, %rdi
cmovbeq %r12, %rdi
addq %rcx, %rdi
movq %r12, %rsi
callq 0x1d3ff
subq %r13, %rax
testq %rax, %rax
je 0x1d3c9
cmpq $0x1f, %rax
jbe 0x1d3e0
movq 0x8(%r15), %rcx
andq $-0x4, %rcx
leaq 0x20(%rax), %rdx
cmpq %rdx, %rcx
jb 0x1d3c9
addq $-0x8, %rax
movq %r15, %rdi
movq %rax, %rsi
callq 0x1d7d5
movq %rax, %r12
orb $0x2, 0x8(%rax)
movq %r15, %rdi
callq 0x1d098
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1cfc5
movq %r12, %r15
jmp 0x1d3c9
xorl %r15d, %r15d
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
jmp 0x1d251
leaq 0x6252(%rip), %rdi      # 0x23639
leaq 0x5fe1(%rip), %rsi      # 0x233cf
leaq 0x626f(%rip), %rcx      # 0x23664
movl $0x37a, %edx            # imm = 0x37A
callq 0x31e0