// File: /workspace/github_c_makefile_star2_O0/USArmyResearchLab[P]ARL_OpenSHMEM/src/xmalloc.c
// Function: free_pages
static inline void
free_pages( struct __xmem_struct* xm, void *ptr, size_t idx, struct pginfo *info)
{
    size_t i;
    struct pgfree *pf, *pt=NULL;
    size_t l;
    void *tail;

    if (info == MALLOC_FREE) {
	wrtwarning("page is already free.\n");
	return;
    }

    if (info != MALLOC_FIRST) {
	wrtwarning("pointer to wrong page.\n");
	return;
    }

    if ((size_t)(uintptr_t)ptr & xm->malloc_pagemask) {
	wrtwarning("modified (page-) pointer.\n");
	return;
    }

    /* Count how many pages and mark them free at the same time */
    xm->page_dir[idx] = MALLOC_FREE;
    for (i = 1; xm->page_dir[idx+i] == MALLOC_FOLLOW; i++)
	xm->page_dir[idx + i] = MALLOC_FREE;

    l = i << xm->malloc_pageshift;

    if (malloc_junk)
	memset(ptr, SOME_JUNK, l);

    if (xm->malloc_hint)
	madvise(ptr, l, MADV_FREE);

    tail = (char *)ptr+l;

    /* add to free-list */
    if (xm->px == NULL)
	xm->px = __host_malloc(sizeof(*xm->px)); /* This cannot fail... */
    xm->px->page = ptr;
    xm->px->end =  tail;
    xm->px->size = l;
    if (xm->free_list.next == NULL) {

	/* Nothing on free list, put this at head */
	xm->px->next = xm->free_list.next;
	xm->px->prev = &xm->free_list;
	xm->free_list.next = xm->px;
	pf = xm->px;
	xm->px = NULL;

    } else {

	/* Find the right spot, leave pf pointing to the modified entry. */
	tail = (char *)ptr+l;

	for(pf = xm->free_list.next; pf->end < ptr && pf->next != NULL;
	    pf = pf->next)
	    ; /* Race ahead here */

	if (pf->page > tail) {
	    /* Insert before entry */
	    xm->px->next = pf;
	    xm->px->prev = pf->prev;
	    pf->prev = xm->px;
	    xm->px->prev->next = xm->px;
	    pf = xm->px;
	    xm->px = NULL;
	} else if (pf->end == ptr ) {
	    /* Append to the previous entry */
	    pf->end = (char *)pf->end + l;
	    pf->size += l;
	    if (pf->next != NULL && pf->end == pf->next->page ) {
		/* And collapse the next too. */
		pt = pf->next;
		pf->end = pt->end;
		pf->size += pt->size;
		pf->next = pt->next;
		if (pf->next != NULL)
		    pf->next->prev = pf;
	    }
	} else if (pf->page == tail) {
	    /* Prepend to entry */
	    pf->size += l;
	    pf->page = ptr;
	} else if (pf->next == NULL) {
	    /* Append at tail of chain */
	    xm->px->next = NULL;
	    xm->px->prev = pf;
	    pf->next = xm->px;
	    pf = xm->px;
	    xm->px = NULL;
	} else {
	    wrterror("freelist is destroyed.\n");
	}
    }
    
    /* Return something to OS ? */
    if (pf->next == NULL &&			/* If we're the last one, */
      pf->size > xm->malloc_cache &&		/* ..and the cache is full, */
      pf->end == xm->malloc_brk &&			/* ..and none behind us, */
      xm->malloc_brk == __sbrk(xm,(intptr_t)0)) {	/* ..and it's OK to do... */

	/*
	 * Keep the cache intact.  Notice that the '>' above guarantees that
	 * the pf will always have at least one page afterwards.
	 */
	pf->end = (char *)pf->page + xm->malloc_cache;
	pf->size = xm->malloc_cache;

	__brk(xm,pf->end);
	xm->malloc_brk = pf->end;

	idx = ptr2idx(pf->end);

	for(i=idx;i <= xm->last_idx;)
	    xm->page_dir[i++] = MALLOC_NOT_MINE;

	xm->last_idx = idx - 1;

	/* XXX: We could realloc/shrink the pagedir here I guess. */
    }
    if (pt != NULL)
	__host_free(pt);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq $0x0, -0x38(%rbp)
movl $0x1, %eax
cmpq %rax, -0x20(%rbp)
jne 0x320c
leaq 0x224e(%rip), %rdi      # 0x5450
callq 0x2ce0
jmp 0x36db
movl $0x2, %eax
cmpq %rax, -0x20(%rbp)
je 0x3228
leaq 0x2249(%rip), %rdi      # 0x5467
callq 0x2ce0
jmp 0x36db
movq -0x10(%rbp), %rax
movq -0x8(%rbp), %rcx
andq 0x10(%rcx), %rax
cmpq $0x0, %rax
je 0x324b
leaq 0x223e(%rip), %rdi      # 0x547f
callq 0x2ce0
jmp 0x36db
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x18(%rbp), %rcx
movl $0x1, %edx
movq %rdx, (%rax,%rcx,8)
movq $0x1, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x18(%rbp), %rcx
addq -0x28(%rbp), %rcx
movl $0x3, %edx
cmpq %rdx, (%rax,%rcx,8)
jne 0x32aa
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x18(%rbp), %rcx
addq -0x28(%rbp), %rcx
movl $0x1, %edx
movq %rdx, (%rax,%rcx,8)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x3268
movq -0x28(%rbp), %rax
movq -0x8(%rbp), %rcx
movq 0x8(%rcx), %rcx
shlq %cl, %rax
movq %rax, -0x40(%rbp)
cmpl $0x0, 0x41d0(%rip)      # 0x7494
je 0x32d8
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rdx
movl $0xd0, %esi
callq 0x1130
movq -0x8(%rbp), %rax
cmpl $0x0, 0x6c(%rax)
je 0x32f4
movq -0x10(%rbp), %rdi
movq -0x40(%rbp), %rsi
movl $0x8, %edx
callq 0x11f0
movq -0x10(%rbp), %rax
addq -0x40(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x8(%rbp), %rax
cmpq $0x0, 0x78(%rax)
jne 0x3320
movl $0x28, %edi
callq 0x2cc0
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x78(%rax)
movq -0x10(%rbp), %rcx
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq %rcx, 0x10(%rax)
movq -0x48(%rbp), %rcx
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq %rcx, 0x18(%rax)
movq -0x40(%rbp), %rcx
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq %rcx, 0x20(%rax)
movq -0x8(%rbp), %rax
cmpq $0x0, 0x40(%rax)
jne 0x33af
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq %rcx, (%rax)
movq -0x8(%rbp), %rcx
addq $0x40, %rcx
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq $0x0, 0x78(%rax)
jmp 0x35b9
movq -0x10(%rbp), %rax
addq -0x40(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x8(%rbp), %rax
movq 0x40(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rcx
xorl %eax, %eax
cmpq -0x10(%rbp), %rcx
movb %al, -0x49(%rbp)
jae 0x33e8
movq -0x30(%rbp), %rax
cmpq $0x0, (%rax)
setne %al
movb %al, -0x49(%rbp)
movb -0x49(%rbp), %al
testb $0x1, %al
jne 0x33f1
jmp 0x3400
jmp 0x33f3
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x33c7
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x48(%rbp), %rax
jbe 0x3475
movq -0x30(%rbp), %rcx
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rcx
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq 0x8(%rax), %rax
movq %rcx, (%rax)
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq $0x0, 0x78(%rax)
jmp 0x35b7
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
cmpq -0x10(%rbp), %rax
jne 0x3527
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rcx
addq -0x40(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x40(%rbp), %rcx
movq -0x30(%rbp), %rax
addq 0x20(%rax), %rcx
movq %rcx, 0x20(%rax)
movq -0x30(%rbp), %rax
cmpq $0x0, (%rax)
je 0x3522
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x30(%rbp), %rcx
movq (%rcx), %rcx
cmpq 0x10(%rcx), %rax
jne 0x3522
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rcx
movq -0x30(%rbp), %rax
addq 0x20(%rax), %rcx
movq %rcx, 0x20(%rax)
movq -0x38(%rbp), %rax
movq (%rax), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
cmpq $0x0, (%rax)
je 0x3520
movq -0x30(%rbp), %rcx
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x8(%rax)
jmp 0x3522
jmp 0x35b5
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
cmpq -0x48(%rbp), %rax
jne 0x3553
movq -0x40(%rbp), %rcx
movq -0x30(%rbp), %rax
addq 0x20(%rax), %rcx
movq %rcx, 0x20(%rax)
movq -0x10(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0x35b3
movq -0x30(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x35a5
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq $0x0, (%rax)
movq -0x30(%rbp), %rcx
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0x8(%rbp), %rax
movq 0x78(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq $0x0, 0x78(%rax)
jmp 0x35b1
leaq 0x1eee(%rip), %rdi      # 0x549a
callq 0x2c00
jmp 0x35b3
jmp 0x35b5
jmp 0x35b7
jmp 0x35b9
movq -0x30(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x36cb
movq -0x30(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x8(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jbe 0x36cb
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x8(%rbp), %rcx
cmpq 0x70(%rcx), %rax
jne 0x36cb
movq -0x8(%rbp), %rax
movq 0x70(%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x8(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x2c40
movq %rax, %rcx
movq -0x58(%rbp), %rax
cmpq %rcx, %rax
jne 0x36cb
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x8(%rbp), %rax
addq 0x18(%rax), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x8(%rbp), %rdi
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rsi
callq 0x3920
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x70(%rax)
movq -0x30(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x8(%rcx), %rcx
shrq %cl, %rax
movq -0x8(%rbp), %rcx
subq 0x20(%rcx), %rax
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x28(%rcx), %rax
ja 0x36bb
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq -0x28(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x28(%rbp)
movq $0x0, (%rax,%rcx,8)
jmp 0x368c
movq -0x18(%rbp), %rcx
subq $0x1, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x28(%rax)
cmpq $0x0, -0x38(%rbp)
je 0x36db
movq -0x38(%rbp), %rdi
callq 0x3980
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)