// File: /workspace/github_c_makefile_star2_O0/Tarsnap[P]kivaloo/kvlds/btree_node_merge.c
// Function: merge_parent
static int
merge_parent(struct btree * T, struct node ** c_in,
    const struct kvldskey ** k_in, struct node ** c_out, size_t nsep)
{
	size_t nkeys;
	size_t i, j;
	const struct kvldskey ** keys;
	struct node ** children;
	struct node * N;

	/* The input nodes are dirty parents. */
	for (i = 0; i <= nsep; i++) {
		assert(c_in[i]->type == NODE_TYPE_PARENT);
		assert(c_in[i]->state == NODE_STATE_DIRTY);
	}

	/* Figure out how big the new node needs to be. */
	for (nkeys = i = 0; i <= nsep; i++)
		nkeys += c_in[i]->nkeys + 1;
	nkeys -= 1;

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

	/* Copy keys into new array. */
	for (j = i = 0; i < nsep; i++) {
		/* Separator keys within a merging node. */
		memcpy(&keys[j], c_in[i]->u.keys,
		    c_in[i]->nkeys * sizeof(const struct kvldskey *));
		j += c_in[i]->nkeys;

		/* Separator keys between merging nodes. */
		keys[j++] = k_in[i];
	}
	memcpy(&keys[j], c_in[i]->u.keys,
	    c_in[i]->nkeys * sizeof(const struct kvldskey *));

	/* Copy children into new array. */
	for (j = i = 0; i <= nsep; j += c_in[i]->nkeys + 1, i++)
		memcpy(&children[j], c_in[i]->v.children,
		    (c_in[i]->nkeys + 1) * sizeof(struct node *));

	/* Create a node. */
	if ((N = btree_node_mkparent(T, c_in[0]->height,
	    nkeys, keys, children)) == NULL)
		goto err2;

	/* Assign a parent to this node. */
	N->p_dirty = c_in[0]->p_dirty;
	btree_node_lock(T, N->p_dirty);

	/* Adjust parentage of children. */
	for (j = 0; j <= nkeys; j++) {
		/* Unlock old parent. */
		if (node_hasplock(children[j]))
			btree_node_unlock(T, children[j]->p_dirty);

		/* Set new dirty parent. */
		children[j]->p_dirty = N;

		/* Lock new parent. */
		if (node_hasplock(children[j]))
			btree_node_lock(T, children[j]->p_dirty);
	}

	/* Destroy old nodes (but not their children). */
	for (i = 0; i <= nsep; i++) {
		free(c_in[i]->u.keys);
		free(c_in[i]->v.children);
		c_in[i]->nkeys = (size_t)(-1);
		btree_node_destroy(T, c_in[i]);
	}

	/* Store created node. */
	c_out[0] = N;

	/* Success! */
	return (0);

err2:
	free(children);
err1:
	free(keys);
err0:
	/* Failure! */
	return (-1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x30(%rbp), %rax
ja 0xe19c
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0xe12d
jmp 0xe14c
leaq 0x118b3(%rip), %rdi     # 0x1f9e7
leaq 0x117b1(%rip), %rsi     # 0x1f8ec
movl $0x51, %edx
leaq 0x118c2(%rip), %rcx     # 0x1fa09
callq 0x21d0
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %al
shrb $0x2, %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x2, %eax
jne 0xe16a
jmp 0xe189
leaq 0x11758(%rip), %rdi     # 0x1f8c9
leaq 0x11774(%rip), %rsi     # 0x1f8ec
movl $0x52, %edx
leaq 0x11885(%rip), %rcx     # 0x1fa09
callq 0x21d0
jmp 0xe18b
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0xe104
movq $0x0, -0x40(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x30(%rbp), %rax
ja 0xe1e0
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x38(%rax), %rax
addq $0x1, %rax
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0xe1ac
movq -0x38(%rbp), %rax
subq $0x1, %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rdi
movl $0x8, %esi
callq 0xe540
movq %rax, -0x50(%rbp)
cmpq $0x0, %rax
jne 0xe210
cmpq $0x0, -0x38(%rbp)
jbe 0xe210
jmp 0xe52c
movq -0x38(%rbp), %rdi
addq $0x1, %rdi
movl $0x8, %esi
callq 0xe540
movq %rax, -0x58(%rbp)
cmpq $0x0, %rax
jne 0xe23f
movq -0x38(%rbp), %rax
addq $0x1, %rax
cmpq $0x0, %rax
jbe 0xe23f
jmp 0xe523
movq $0x0, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x30(%rbp), %rax
jae 0xe2e1
movq -0x50(%rbp), %rdi
movq -0x48(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x40(%rax), %rsi
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x38(%rax), %rdx
shlq $0x3, %rdx
callq 0x2280
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x38(%rax), %rax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, -0x48(%rbp)
movq %rdx, (%rax,%rcx,8)
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0xe24f
movq -0x50(%rbp), %rdi
movq -0x48(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x40(%rax), %rsi
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x38(%rax), %rdx
shlq $0x3, %rdx
callq 0x2280
movq $0x0, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x30(%rbp), %rax
ja 0xe399
movq -0x58(%rbp), %rdi
movq -0x48(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rdi
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x48(%rax), %rsi
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x38(%rax), %rdx
addq $0x1, %rdx
shlq $0x3, %rdx
callq 0x2280
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x38(%rax), %rax
addq $0x1, %rax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0xe329
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq (%rax), %rax
movsbl 0x1d(%rax), %edx
movq -0x38(%rbp), %rcx
movq -0x50(%rbp), %r8
movq -0x58(%rbp), %r9
xorl %esi, %esi
xorl %eax, %eax
movq $0x0, (%rsp)
callq 0xbe40
movq %rax, -0x60(%rbp)
cmpq $0x0, %rax
jne 0xe3d4
jmp 0xe51a
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq 0x28(%rax), %rcx
movq -0x60(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x10(%rbp), %rdi
movq -0x60(%rbp), %rax
movq 0x28(%rax), %rsi
callq 0xe5e0
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq -0x38(%rbp), %rax
ja 0xe493
movq -0x58(%rbp), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xe670
cmpl $0x0, %eax
je 0xe43d
movq -0x10(%rbp), %rdi
movq -0x58(%rbp), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x28(%rax), %rsi
callq 0xe6a0
movq -0x60(%rbp), %rcx
movq -0x58(%rbp), %rax
movq -0x48(%rbp), %rdx
movq (%rax,%rdx,8), %rax
movq %rcx, 0x28(%rax)
movq -0x58(%rbp), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xe670
cmpl $0x0, %eax
je 0xe480
movq -0x10(%rbp), %rdi
movq -0x58(%rbp), %rax
movq -0x48(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x28(%rax), %rsi
callq 0xe5e0
jmp 0xe482
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0xe400
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x30(%rbp), %rax
ja 0xe506
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x40(%rax), %rdi
callq 0x2040
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x48(%rax), %rdi
callq 0x2040
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq $-0x1, 0x38(%rax)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0xc2e0
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0xe49b
movq -0x60(%rbp), %rcx
movq -0x28(%rbp), %rax
movq %rcx, (%rax)
movl $0x0, -0x4(%rbp)
jmp 0xe533
movq -0x58(%rbp), %rdi
callq 0x2040
movq -0x50(%rbp), %rdi
callq 0x2040
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax)