// File: /workspace/github_c_makefile_star2_O3/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 %rbx
movq (%rdi), %rbx
testq %rbx, %rbx
je 0xd289
movq 0x8(%rdi), %rax
testb $0x1, %bl
je 0xd258
movl 0xf(%rbx), %ecx
cmpq %rcx, %rax
jbe 0xd242
movzbl (%rdx,%rcx), %ecx
jmp 0xd244
xorl %ecx, %ecx
movzbl 0x13(%rbx), %r8d
orl %r8d, %ecx
incl %ecx
shrl $0x8, %ecx
movq -0x1(%rbx,%rcx,8), %rbx
jmp 0xd22f
xorl %r8d, %r8d
testq %rax, %rax
je 0xd275
movb (%rbx,%r8), %r10b
movb (%rdx,%r8), %cl
cmpb %cl, %r10b
jne 0xd294
incl %r8d
cmpq %r8, %rax
ja 0xd260
movb (%rbx,%r8), %r10b
movl %r10d, %ecx
testb %r10b, %r10b
jne 0xd297
callq *0x18(%rdi)
jmp 0xd334
movq %rdx, (%rdi)
callq *0x18(%rdi)
jmp 0xd332
xorb %r10b, %cl
movzbl %cl, %r11d
bsrl %r11d, %ecx
movl $0x1, %ebx
shll %cl, %ebx
notb %bl
xorl %r9d, %r9d
cmpb $0x1, %r11b
sbbl %r9d, %r9d
orb %bl, %r9b
orb %r9b, %r10b
movzbl %r10b, %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 0xd326
movl 0xf(%r10), %r11d
cmpl %r8d, %r11d
ja 0xd326
cmpl %r8d, %r11d
jne 0xd2f6
cmpb %r9b, 0x13(%r10)
ja 0xd326
movl %r11d, %edi
cmpq %rdi, %rax
jbe 0xd305
movzbl (%rdx,%rdi), %r11d
jmp 0xd308
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 0xd2dc
movl %ecx, %eax
movq %r10, (%rsi,%rax,8)
incq %rsi
movq %rsi, (%rdi)
xorl %ebx, %ebx
movq %rbx, %rax
popq %rbx
retq