// File: /workspace/github_c_makefile_star2_O3/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 %r12
pushq %rbx
pushq %rax
movq %rsi, %r12
movq %rdi, %rbx
leaq -0x1(%rdx), %rax
movl $0xfffffffe, %ecx       # imm = 0xFFFFFFFE
cmpq %rcx, %rax
ja 0x22233
addq $0x7, %rdx
movabsq $0x1fffffff8, %rax      # imm = 0x1FFFFFFF8
andq %rdx, %rax
cmpq $0x19, %rax
movl $0x18, %r14d
cmovaeq %rax, %r14
jmp 0x22236
xorl %r14d, %r14d
leaq (%r12,%r14), %rdi
addq $0x20, %rdi
movq %r12, %rsi
callq 0x22004
cmpq $0x9, %r12
cmovbq %r14, %rax
movq %rbx, %rdi
movq %rax, %rsi
callq 0x22054
testq %rax, %rax
je 0x222fe
leaq -0x1(%r12), %rdx
testq %rdx, %r12
jne 0x2231a
movq %rax, %r15
addq $0x10, %rax
leaq (%r12,%r15), %rcx
addq $0xf, %rcx
movq %r12, %rdi
negq %rdi
andq %rdi, %rcx
movq %rcx, %rsi
subq %rax, %rsi
leaq -0x1(%rsi), %r8
cmpq $0x1e, %r8
ja 0x222b7
movl $0x20, %r8d
subq %rsi, %r8
cmpq %r12, %r8
cmovbeq %r12, %r8
addq %rdx, %rcx
addq %r8, %rcx
andq %rdi, %rcx
subq %rax, %rcx
movq %rcx, %rsi
testq %rsi, %rsi
je 0x22301
cmpq $0x1f, %rsi
jbe 0x22339
movq 0x8(%r15), %rax
andq $-0x4, %rax
leaq 0x20(%rsi), %rcx
cmpq %rcx, %rax
jb 0x22301
addq $-0x8, %rsi
movq %r15, %rdi
callq 0x22719
movq %rax, %r12
orb $0x2, 0x8(%rax)
movq %r15, %rdi
callq 0x21f71
movq %rbx, %rdi
movq %r15, %rsi
callq 0x21e84
movq %r12, %r15
jmp 0x22301
xorl %r15d, %r15d
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x22173
leaq 0x6334(%rip), %rdi      # 0x28655
leaq 0x5f3c(%rip), %rsi      # 0x28264
leaq 0x6703(%rip), %rcx      # 0x28a32
movl $0x123, %edx            # imm = 0x123
callq 0x31e0
leaq 0x618e(%rip), %rdi      # 0x284ce
leaq 0x5f1d(%rip), %rsi      # 0x28264
leaq 0x61ab(%rip), %rcx      # 0x284f9
movl $0x37a, %edx            # imm = 0x37A
callq 0x31e0