// File: /workspace/github_c_makefile_star2_O1/glk[P]critbit/critbit.c
// Function: critbit_buf_insert
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 %rbx
pushq %rax
movq (%rdi), %rbx
testq %rbx, %rbx
je 0xd27f
movq 0x8(%rdi), %rax
testb $0x1, %bl
je 0xd25a
movl 0xf(%rbx), %ecx
cmpq %rcx, %rax
jbe 0xd244
movzbl (%rdx,%rcx), %ecx
jmp 0xd246
xorl %ecx, %ecx
movzbl 0x13(%rbx), %r8d
orl %r8d, %ecx
incl %ecx
shrl $0x8, %ecx
movq -0x1(%rbx,%rcx,8), %rbx
jmp 0xd231
testq %rax, %rax
je 0xd28a
xorl %r10d, %r10d
xorl %r8d, %r8d
movb (%rbx,%r10), %r9b
movb (%rdx,%r10), %cl
cmpb %cl, %r9b
jne 0xd2a0
incl %r8d
movq %r8, %r10
cmpq %r8, %rax
ja 0xd265
jmp 0xd290
movq %rdx, (%rdi)
callq *0x18(%rdi)
jmp 0xd342
xorl %r8d, %r8d
xorl %r10d, %r10d
movb (%rbx,%r10), %cl
testb %cl, %cl
jne 0xd2a3
callq *0x18(%rdi)
jmp 0xd344
xorb %r9b, %cl
movzbl %cl, %r11d
bsrl %r11d, %ecx
movl $0x1, %ebp
shll %cl, %ebp
notb %bpl
xorl %r9d, %r9d
cmpb $0x1, %r11b
sbbl %r9d, %r9d
orb %bpl, %r9b
movb (%rbx,%r10), %cl
orb %r9b, %cl
movzbl %cl, %ecx
incl %ecx
shrl $0x8, %ecx
movl %r8d, 0x10(%rsi)
movb %r9b, 0x14(%rsi)
leal (,%rcx,8), %r10d
xorl $0x8, %r10d
movq %rdx, (%rsi,%r10)
movq (%rdi), %r10
testb $0x1, %r10b
je 0xd336
movl 0xf(%r10), %r11d
cmpl %r8d, %r11d
ja 0xd336
cmpl %r8d, %r11d
jne 0xd306
cmpb %r9b, 0x13(%r10)
ja 0xd336
movl %r11d, %edi
cmpq %rdi, %rax
jbe 0xd315
movzbl (%rdx,%rdi), %r11d
jmp 0xd318
xorl %r11d, %r11d
leaq -0x1(%r10), %rdi
movzbl 0x13(%r10), %ebx
orl %ebx, %r11d
incl %r11d
shrl $0x8, %r11d
leaq (%rdi,%r11,8), %rdi
movq -0x1(%r10,%r11,8), %r10
jmp 0xd2ec
movl %ecx, %eax
movq %r10, (%rsi,%rax,8)
incq %rsi
movq %rsi, (%rdi)
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %rbp
retq