// File: /workspace/github_c_makefile_star2_O2/glk[P]critbit/critbit.c
// Function: critbit_insert_impl
static __inline struct critbit_key *
critbit_insert_impl(struct critbit_tree *t, struct critbit_node *newnode,
    const struct critbit_key *key, size_t keylen, critbit_keybuf_t *keybuf)
{
	const uint8_t *const ubytes = keybuf(key);
	struct critbit_node *q;
	struct critbit_ref *p;
	const uint8_t *pkey;
	uint32_t newbyte;
	uint32_t newotherbits;
	uint8_t c;

	p = t->ct_root;
	if (p == NULL) {
		critbit_ref_set_key(&t->ct_root, key);
		critbit_node_free(t, newnode);
		return (NULL);
	}

	while (critbit_ref_is_internal(p)) {
		q = critbit_ref_get_node(p);

		c = 0;
		if (q->byte < keylen)
			c = ubytes[q->byte];

		const int direction = (1 + (q->otherbits | c)) >> 8;
		p = q->child[direction];
	}

	pkey = keybuf(critbit_ref_get_key(p));
	for (newbyte = 0; newbyte < keylen; ++newbyte) {
		if (pkey[newbyte] != ubytes[newbyte]) {
			newotherbits = pkey[newbyte] ^ ubytes[newbyte];
			goto different_byte_found;
		}
	}

	if (pkey[newbyte] != 0) {
		newotherbits = pkey[newbyte];
		goto different_byte_found;
	}

	critbit_node_free(t, newnode);
	return (critbit_ref_get_key(p));

different_byte_found:

	newotherbits = ms1b8(newotherbits) ^ 255;
	const int newdirection = (1 + (newotherbits | pkey[newbyte])) >> 8;

	newnode->byte = newbyte;
	newnode->otherbits = newotherbits;
	critbit_ref_set_key(&newnode->child[1 - newdirection], key);

	struct critbit_ref **wherep = &t->ct_root;
	for (;;) {
		p = *wherep;
		if (!critbit_ref_is_internal(p))
			break;
		q = critbit_ref_get_node(p);
		if (q->byte > newbyte)
			break;
		if (q->byte == newbyte && q->otherbits > newotherbits)
			break;
		c = 0;
		if (q->byte < keylen)
			c = ubytes[q->byte];
		const int direction = (1 + (q->otherbits | c)) >> 8;
		wherep = q->child + direction;
	}

	newnode->child[newdirection] = *wherep;
	critbit_ref_set_node(wherep, newnode);

	return (NULL);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %r14
movq %rdx, %rbx
movq %rsi, %r13
movq %rdi, %r12
movq %rdx, %rdi
movq %r8, (%rsp)
callq *%r8
movq (%r12), %rbp
testq %rbp, %rbp
je 0xd2de
movq %rax, %r15
testb $0x1, %bpl
je 0xd2be
movl 0xf(%rbp), %eax
cmpq %r14, %rax
jae 0xd2aa
movzbl (%r15,%rax), %eax
jmp 0xd2ac
xorl %eax, %eax
movzbl 0x13(%rbp), %ecx
orl %ecx, %eax
incl %eax
shrl $0x8, %eax
movq -0x1(%rbp,%rax,8), %rbp
jmp 0xd295
movq %rbp, %rdi
callq *(%rsp)
xorl %edx, %edx
movl %edx, %ecx
movb (%rax,%rcx), %r10b
cmpq %r14, %rcx
jae 0xd2f2
movb (%r15,%rcx), %cl
cmpb %cl, %r10b
jne 0xd30a
incl %edx
jmp 0xd2c6
movq %rbx, (%r12)
movq %r12, %rdi
movq %r13, %rsi
callq *0x18(%r12)
jmp 0xd399
movl %r10d, %ecx
testb %r10b, %r10b
jne 0xd30d
movq %r12, %rdi
movq %r13, %rsi
callq *0x18(%r12)
jmp 0xd39b
xorb %r10b, %cl
movzbl %cl, %edi
bsrl %edi, %ecx
pushq $0x1
popq %r8
shll %cl, %r8d
notb %r8b
xorl %eax, %eax
cmpb $0x1, %dil
sbbl %eax, %eax
orb %r8b, %al
orb %al, %r10b
movzbl %r10b, %ecx
incl %ecx
shrl $0x8, %ecx
movl %edx, 0x10(%r13)
movb %al, 0x14(%r13)
leal (,%rcx,8), %edi
xorl $0x8, %edi
movq %rbx, (%r13,%rdi)
movq (%r12), %r9
testb $0x1, %r9b
je 0xd38b
movl 0xf(%r9), %edi
cmpl %edx, %edi
ja 0xd38b
cmpl %edx, %edi
jne 0xd367
cmpb %al, 0x13(%r9)
ja 0xd38b
cmpq %r14, %rdi
jae 0xd373
movzbl (%r15,%rdi), %edi
jmp 0xd375
xorl %edi, %edi
movzbl 0x13(%r9), %r8d
decq %r9
orl %r8d, %edi
incl %edi
shrl $0x8, %edi
leaq (%r9,%rdi,8), %r12
jmp 0xd34b
movl %ecx, %eax
movq %r9, (%r13,%rax,8)
incq %r13
movq %r13, (%r12)
xorl %ebp, %ebp
movq %rbp, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq