// File: /workspace/github_c_makefile_star2_O0/Tarsnap[P]kivaloo/kvlds/btree_balance.c
// Function: domergenode
static int
domergenode(struct balance_cookie * B, struct node * N)
{
	size_t nmerges, i, j;
	size_t nmerge;
	int failed = 0;		/* We haven't failed yet. */
	int merging;
	struct node * NC;

	/*
	 * As far as we know, we've done all possibly merges under this
	 * subtree.  (We'll adjust this later if necessary).
	 */
	N->needmerge = 0;

	/* If this node is not dirty, it doesn't need merging. */
	if (N->state != NODE_STATE_DIRTY)
		goto done;

	/* If this node has no children, do nothing. */
	if (N->type != NODE_TYPE_PARENT)
		goto done;

	/* Perform merges under our children first. */
	for (i = 0; i <= N->nkeys; i++) {
		/* Perform merges under this child. */
		if (domergenode(B, N->v.children[i]))
			goto err0;

		/* If this child needs to be remerged, so do we. */
		if (N->v.children[i]->needmerge)
			N->needmerge = 1;
	}

	/* Count how many of our children will be merged. */
	for (nmerges = i = 0; i <= N->nkeys; i++) {
		if (N->v.children[i]->merging) {
			/* We have a merge required. */
			nmerges++;

			/* We might need to do a merge in the new child. */
			N->needmerge = 1;
		}
	}

	/* If we don't need to do any merges, we're done. */
	if (nmerges == 0)
		goto done;

	/* Iterate through the children, dirtying and unlocking them. */
	for (merging = 0, i = 0;
	    i <= N->nkeys;
	    merging = N->v.children[i]->merging, i++) {
		/*
		 * Grab a pointer to the node.  Note that if we dirty NC, it
		 * will no longer be the same as N->v.children[i].
		 */
		NC = N->v.children[i];

		/* If this node isn't being merged, move on. */
		if ((NC->merging == 0) && (merging == 0))
			continue;

		/* If this node isn't dirty, make it dirty. */
		if (NC->state != NODE_STATE_DIRTY) {
			if (btree_node_dirty(B->T, NC) == NULL)
				failed = 1;

			/* The dirty node is being merged, not the shadow. */
			N->v.children[i]->merging = NC->merging;
			NC->merging = 0;
		}

		/*
		 * Release the lock we picked up in planmergenode or which
		 * was picked up for us by btree_node_fetch.
		 */
		btree_node_unlock(B->T, NC);
	}

	/* If we failed to dirty a node, give up now. */
	if (failed)
		goto err0;

	/* Iterate through the children, merging them as necessary. */
	for (nmerge = 0, j = i = 0; i <= N->nkeys; i++) {
		/* If this node is being merged into the next, move on. */
		if (N->v.children[i]->merging) {
			nmerge++;
			continue;
		}

		/* If we're not merging, just copy the child and key. */
		if (nmerge == 0) {
			N->v.children[j] = N->v.children[i];
			if (i < N->nkeys)
				N->u.keys[j] = N->u.keys[i];
			j += 1;
			continue;
		}

		/* Merge children. */
		if (btree_node_merge(B->T,
		    &N->v.children[i - nmerge], &N->u.keys[i - nmerge],
		    &N->v.children[j], &N->u.keys[j], nmerge)) {
			j += nmerge;
			failed = 1;
		}

		/* Copy the separator key. */
		if (i < N->nkeys)
			N->u.keys[j] = N->u.keys[i];
		j += 1;

		/* We've merged this batch; start over. */
		nmerge = 0;
	}

	/* Store number of keys. */
	N->nkeys = j - 1;

	/* The size of this node has changed. */
	N->pagesize = (uint32_t)(-1);

	/* Did we fail? */
	if (failed)
		goto err0;

done:
	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl $0x0, -0x3c(%rbp)
movq -0x18(%rbp), %rax
movb 0x1c(%rax), %cl
andb $-0x41, %cl
orb $0x0, %cl
movb %cl, 0x1c(%rax)
movq -0x18(%rbp), %rax
movb 0x1c(%rax), %al
shrb $0x2, %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x2, %eax
je 0x8c70
jmp 0x903e
movq -0x18(%rbp), %rax
movb 0x1c(%rax), %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x8c86
jmp 0x903e
movq $0x0, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x38(%rcx), %rax
ja 0x8cff
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x8c30
cmpl $0x0, %eax
je 0x8cbf
jmp 0x9047
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %al
shrb $0x6, %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x8cef
movq -0x18(%rbp), %rax
movb 0x1c(%rax), %cl
andb $-0x41, %cl
orb $0x40, %cl
movb %cl, 0x1c(%rax)
jmp 0x8cf1
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x8c8e
movq $0x0, -0x28(%rbp)
movq $0x0, -0x20(%rbp)
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x38(%rcx), %rax
ja 0x8d69
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %al
shrb $0x5, %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x8d59
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movb 0x1c(%rax), %cl
andb $-0x41, %cl
orb $0x40, %cl
movb %cl, 0x1c(%rax)
jmp 0x8d5b
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x8d0f
cmpq $0x0, -0x20(%rbp)
jne 0x8d75
jmp 0x903e
movl $0x0, -0x40(%rbp)
movq $0x0, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x38(%rcx), %rax
ja 0x8e7d
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movb 0x1c(%rax), %al
shrb $0x5, %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x8dc9
cmpl $0x0, -0x40(%rbp)
jne 0x8dc9
jmp 0x8e4e
movq -0x48(%rbp), %rax
movb 0x1c(%rax), %al
shrb $0x2, %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x2, %eax
je 0x8e3d
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x48(%rbp), %rsi
callq 0xc5a0
cmpq $0x0, %rax
jne 0x8dfb
movl $0x1, -0x3c(%rbp)
movq -0x48(%rbp), %rax
movb 0x1c(%rax), %al
shrb $0x5, %al
andb $0x1, %al
movzbl %al, %ecx
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rdx
movq (%rax,%rdx,8), %rax
movb %cl, %dl
movb 0x1c(%rax), %cl
andb $0x1, %dl
shlb $0x5, %dl
andb $-0x21, %cl
orb %dl, %cl
movb %cl, 0x1c(%rax)
movq -0x48(%rbp), %rax
movb 0x1c(%rax), %cl
andb $-0x21, %cl
orb $0x0, %cl
movb %cl, 0x1c(%rax)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x48(%rbp), %rsi
callq 0x86e0
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %al
shrb $0x5, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x40(%rbp)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x8d84
cmpl $0x0, -0x3c(%rbp)
je 0x8e88
jmp 0x9047
movq $0x0, -0x38(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x38(%rcx), %rax
ja 0x9019
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %al
shrb $0x5, %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x8ee3
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x9008
cmpq $0x0, -0x38(%rbp)
jne 0x8f49
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x30(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x38(%rcx), %rax
jae 0x8f38
movq -0x18(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
movq -0x18(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x30(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0x9008
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rsi
movq -0x28(%rbp), %rax
subq -0x38(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
movq -0x18(%rbp), %rax
movq 0x40(%rax), %rdx
movq -0x28(%rbp), %rax
subq -0x38(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdx
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rcx
movq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rcx
movq -0x18(%rbp), %rax
movq 0x40(%rax), %r8
movq -0x30(%rbp), %rax
shlq $0x3, %rax
addq %rax, %r8
movq -0x38(%rbp), %r9
callq 0xdd60
cmpl $0x0, %eax
je 0x8fc6
movq -0x38(%rbp), %rax
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movl $0x1, -0x3c(%rbp)
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x38(%rcx), %rax
jae 0x8ff4
movq -0x18(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
movq -0x18(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x30(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x8ea0
movq -0x30(%rbp), %rcx
subq $0x1, %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x18(%rbp), %rax
movl $0xffffffff, 0x18(%rax) # imm = 0xFFFFFFFF
cmpl $0x0, -0x3c(%rbp)
je 0x903c
jmp 0x9047
jmp 0x903e
movl $0x0, -0x4(%rbp)
jmp 0x904e
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopw (%rax,%rax)