// File: /workspace/github_c_makefile_star2_O0/Tarsnap[P]kivaloo/kvlds/btree_balance.c
// Function: splitroot
static struct node *
splitroot(struct btree * T, struct node * N)
{
	size_t nkeys;
	const struct kvldskey ** keys;
	struct node ** children;
	struct node * R;
	size_t nparts;
	size_t i;

	/* Figure out how many separator keys we will have. */
	nkeys = btree_node_split_nparts(T, N) - 1;

	/* Allocate vectors for keys and children. */
	if (IMALLOC(keys, nkeys, const struct kvldskey *))
		goto err0;
	if (IMALLOC(children, nkeys + 1, struct node *))
		goto err1;

	/*
	 * Make sure we're not creating a tree which is insanely tall.  Our
	 * balancing invariants result in the tree width doubling at each
	 * level, so there's no way we can reach height 64 without running
	 * out of pages of storage first.
	 */
	assert(N->height + 1 < 64);

	/* Create a parent node. */
	if ((R = btree_node_mkparent(T, N->height + 1,
	    nkeys, keys, children)) == NULL)
		goto err2;
	T->nnodes++;

	/* Mark the new node as a root. */
	R->root = 1;
	btree_node_lock(T, R);

	/* Remove the root marker on the old root. */
	N->root = 0;
	btree_node_unlock(T, N);

	/* Tell ${N} that it has a new dirty parent. */
	N->p_dirty = R;
	btree_node_lock(T, R);

	/* Split the node, writing keys and new nodes into the new root. */
	if (btree_node_split(T, N, R->u.keys, R->v.children, &nparts))
		goto err3;

	/* Sanity check the number of children. */
	assert(nparts == R->nkeys + 1);

	/* Tell the new children who their parent is. */
	for (i = 0; i <= R->nkeys; i++) {
		/* The child has a dirty parent. */
		R->v.children[i]->p_dirty = R;

		/* The child might have a lock on the parent. */
		if (node_hasplock(R->v.children[i]))
			btree_node_lock(T, R);
	}

	/* Success! */
	return (R);

err3:
	/* Turn ${N} back into a root. */
	N->root = 1;
	btree_node_lock(T, N);

	/* Release the root lock on ${R}. */
	btree_node_unlock(T, R);

	/*
	 * Destroy ${R}, including key and child arrays, but don't free
	 * keys or children (since btree_node_split returns with those
	 * already cleaned up).
	 */
	R->nkeys = (size_t)(-1);
	btree_node_destroy(T, R);
	goto err0;
err2:
	free(children);
err1:
	free(keys);
err0:
	/* Failure! */
	return (NULL);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0xd0a0
subq $0x1, %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
movl $0x8, %esi
callq 0x85b0
movq %rax, -0x28(%rbp)
cmpq $0x0, %rax
jne 0x8339
cmpq $0x0, -0x20(%rbp)
jbe 0x8339
jmp 0x855e
movq -0x20(%rbp), %rdi
addq $0x1, %rdi
movl $0x8, %esi
callq 0x85b0
movq %rax, -0x30(%rbp)
cmpq $0x0, %rax
jne 0x8368
movq -0x20(%rbp), %rax
addq $0x1, %rax
cmpq $0x0, %rax
jbe 0x8368
jmp 0x8555
movq -0x18(%rbp), %rax
movsbl 0x1d(%rax), %eax
addl $0x1, %eax
cmpl $0x40, %eax
jge 0x837a
jmp 0x8399
leaq 0x16b70(%rip), %rdi     # 0x1eef1
leaq 0x16acd(%rip), %rsi     # 0x1ee55
movl $0xbe, %edx
leaq 0x16b70(%rip), %rcx     # 0x1ef04
callq 0x21d0
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movsbl 0x1d(%rax), %edx
addl $0x1, %edx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movq -0x30(%rbp), %r9
xorl %esi, %esi
xorl %eax, %eax
movq $0x0, (%rsp)
callq 0xbe40
movq %rax, -0x38(%rbp)
cmpq $0x0, %rax
jne 0x83d4
jmp 0x854c
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x48(%rax)
movq -0x38(%rbp), %rax
movb 0x1c(%rax), %cl
andb $-0x11, %cl
orb $0x10, %cl
movb %cl, 0x1c(%rax)
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x8650
movq -0x18(%rbp), %rax
movb 0x1c(%rax), %cl
andb $-0x11, %cl
orb $0x0, %cl
movb %cl, 0x1c(%rax)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x86e0
movq -0x38(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x8650
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x38(%rbp), %rax
movq 0x40(%rax), %rdx
movq -0x38(%rbp), %rax
movq 0x48(%rax), %rcx
leaq -0x40(%rbp), %r8
callq 0xd2e0
cmpl $0x0, %eax
je 0x8462
jmp 0x8507
movq -0x40(%rbp), %rax
movq -0x38(%rbp), %rcx
movq 0x38(%rcx), %rcx
addq $0x1, %rcx
cmpq %rcx, %rax
jne 0x8479
jmp 0x8498
leaq 0x16aba(%rip), %rdi     # 0x1ef3a
leaq 0x169ce(%rip), %rsi     # 0x1ee55
movl $0xd7, %edx
leaq 0x16a71(%rip), %rcx     # 0x1ef04
callq 0x21d0
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq -0x38(%rbp), %rcx
cmpq 0x38(%rcx), %rax
ja 0x84fd
movq -0x38(%rbp), %rcx
movq -0x38(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x48(%rbp), %rdx
movq (%rax,%rdx,8), %rax
movq %rcx, 0x28(%rax)
movq -0x38(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x8710
cmpl $0x0, %eax
je 0x84ed
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x8650
jmp 0x84ef
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x84a0
movq -0x38(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x8566
movq -0x18(%rbp), %rax
movb 0x1c(%rax), %cl
andb $-0x11, %cl
orb $0x10, %cl
movb %cl, 0x1c(%rax)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x8650
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0x86e0
movq -0x38(%rbp), %rax
movq $-0x1, 0x38(%rax)
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
callq 0xc2e0
jmp 0x855e
movq -0x30(%rbp), %rdi
callq 0x2040
movq -0x28(%rbp), %rdi
callq 0x2040
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq