// File: Ciaxur[P]yagb-emu/include/imgui/imgui.cpp
// Function: ImTextCharFromUtf8(unsigned int*, char const*, char const*)
int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end)
{
    static const char lengths[32] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0 };
    static const int masks[]  = { 0x00, 0x7f, 0x1f, 0x0f, 0x07 };
    static const uint32_t mins[] = { 0x400000, 0, 0x80, 0x800, 0x10000 };
    static const int shiftc[] = { 0, 18, 12, 6, 0 };
    static const int shifte[] = { 0, 6, 4, 2, 0 };
    int len = lengths[*(const unsigned char*)in_text >> 3];
    int wanted = len + !len;

    if (in_text_end == NULL)
        in_text_end = in_text + wanted; // Max length, nulls will be taken into account.

    // Copy at most 'len' bytes, stop copying at 0 or past in_text_end. Branch predictor does a good job here,
    // so it is fast even with excessive branching.
    unsigned char s[4];
    s[0] = in_text + 0 < in_text_end ? in_text[0] : 0;
    s[1] = in_text + 1 < in_text_end ? in_text[1] : 0;
    s[2] = in_text + 2 < in_text_end ? in_text[2] : 0;
    s[3] = in_text + 3 < in_text_end ? in_text[3] : 0;

    // Assume a four-byte character and load four bytes. Unused bits are shifted out.
    *out_char  = (uint32_t)(s[0] & masks[len]) << 18;
    *out_char |= (uint32_t)(s[1] & 0x3f) << 12;
    *out_char |= (uint32_t)(s[2] & 0x3f) <<  6;
    *out_char |= (uint32_t)(s[3] & 0x3f) <<  0;
    *out_char >>= shiftc[len];

    // Accumulate the various error conditions.
    int e = 0;
    e  = (*out_char < mins[len]) << 6; // non-canonical encoding
    e |= ((*out_char >> 11) == 0x1b) << 7;  // surrogate half?
    e |= (*out_char > IM_UNICODE_CODEPOINT_MAX) << 8;  // out of range?
    e |= (s[1] & 0xc0) >> 2;
    e |= (s[2] & 0xc0) >> 4;
    e |= (s[3]       ) >> 6;
    e ^= 0x2a; // top two bits of each tail byte correct?
    e >>= shifte[len];

    if (e)
    {
        // No bytes are consumed when *in_text == 0 || in_text == in_text_end.
        // One byte is consumed in case of invalid first byte of in_text.
        // All available bytes (at most `len` bytes) are consumed on incomplete/invalid second to last bytes.
        // Invalid or incomplete input may consume less bytes than wanted, therefore every byte has to be inspected in s.
        wanted = ImMin(wanted, !!s[0] + !!s[1] + !!s[2] + !!s[3]);
        *out_char = IM_UNICODE_CODEPOINT_INVALID;
    }

    return wanted;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movzbl (%rax), %eax
sarl $0x3, %eax
movslq %eax, %rcx
leaq 0xaf628(%rip), %rax     # 0x172d20
movsbl (%rax,%rcx), %eax
movl %eax, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl $0x0, -0x1c(%rbp)
setne %cl
xorb $-0x1, %cl
andb $0x1, %cl
movzbl %cl, %ecx
addl %ecx, %eax
movl %eax, -0x20(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0xc372d
movq -0x10(%rbp), %rax
movslq -0x20(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0xc3743
movq -0x10(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x2c(%rbp)
jmp 0xc374a
xorl %eax, %eax
movl %eax, -0x2c(%rbp)
jmp 0xc374a
movl -0x2c(%rbp), %eax
movb %al, -0x24(%rbp)
movq -0x10(%rbp), %rax
addq $0x1, %rax
cmpq -0x18(%rbp), %rax
jae 0xc376b
movq -0x10(%rbp), %rax
movsbl 0x1(%rax), %eax
movl %eax, -0x30(%rbp)
jmp 0xc3772
xorl %eax, %eax
movl %eax, -0x30(%rbp)
jmp 0xc3772
movl -0x30(%rbp), %eax
movb %al, -0x23(%rbp)
movq -0x10(%rbp), %rax
addq $0x2, %rax
cmpq -0x18(%rbp), %rax
jae 0xc3793
movq -0x10(%rbp), %rax
movsbl 0x2(%rax), %eax
movl %eax, -0x34(%rbp)
jmp 0xc379a
xorl %eax, %eax
movl %eax, -0x34(%rbp)
jmp 0xc379a
movl -0x34(%rbp), %eax
movb %al, -0x22(%rbp)
movq -0x10(%rbp), %rax
addq $0x3, %rax
cmpq -0x18(%rbp), %rax
jae 0xc37bb
movq -0x10(%rbp), %rax
movsbl 0x3(%rax), %eax
movl %eax, -0x38(%rbp)
jmp 0xc37c2
xorl %eax, %eax
movl %eax, -0x38(%rbp)
jmp 0xc37c2
movl -0x38(%rbp), %eax
movb %al, -0x21(%rbp)
movzbl -0x24(%rbp), %ecx
movslq -0x1c(%rbp), %rdx
leaq 0xaf569(%rip), %rax     # 0x172d40
andl (%rax,%rdx,4), %ecx
shll $0x12, %ecx
movq -0x8(%rbp), %rax
movl %ecx, (%rax)
movzbl -0x23(%rbp), %ecx
andl $0x3f, %ecx
shll $0xc, %ecx
movq -0x8(%rbp), %rax
orl (%rax), %ecx
movl %ecx, (%rax)
movzbl -0x22(%rbp), %ecx
andl $0x3f, %ecx
shll $0x6, %ecx
movq -0x8(%rbp), %rax
orl (%rax), %ecx
movl %ecx, (%rax)
movzbl -0x21(%rbp), %ecx
andl $0x3f, %ecx
shll $0x0, %ecx
movq -0x8(%rbp), %rax
orl (%rax), %ecx
movl %ecx, (%rax)
movslq -0x1c(%rbp), %rcx
leaq 0xaf55c(%rip), %rax     # 0x172d80
movl (%rax,%rcx,4), %ecx
movq -0x8(%rbp), %rax
movl (%rax), %edx
shrl %cl, %edx
movl %edx, %ecx
movl %ecx, (%rax)
movl $0x0, -0x28(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
movslq -0x1c(%rbp), %rdx
leaq 0xaf515(%rip), %rcx     # 0x172d60
cmpl (%rcx,%rdx,4), %eax
setb %al
andb $0x1, %al
movzbl %al, %eax
shll $0x6, %eax
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rax
movl (%rax), %eax
shrl $0xb, %eax
cmpl $0x1b, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
shll $0x7, %eax
orl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rax
cmpl $0xffff, (%rax)         # imm = 0xFFFF
seta %al
andb $0x1, %al
movzbl %al, %eax
shll $0x8, %eax
orl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
movzbl -0x23(%rbp), %eax
andl $0xc0, %eax
sarl $0x2, %eax
orl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
movzbl -0x22(%rbp), %eax
andl $0xc0, %eax
sarl $0x4, %eax
orl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
movzbl -0x21(%rbp), %eax
sarl $0x6, %eax
orl -0x28(%rbp), %eax
movl %eax, -0x28(%rbp)
movl -0x28(%rbp), %eax
xorl $0x2a, %eax
movl %eax, -0x28(%rbp)
movslq -0x1c(%rbp), %rcx
leaq 0xaf4c7(%rip), %rax     # 0x172da0
movl (%rax,%rcx,4), %ecx
movl -0x28(%rbp), %eax
sarl %cl, %eax
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
je 0xc3945
movl -0x20(%rbp), %edi
cmpb $0x0, -0x24(%rbp)
setne %al
xorb $-0x1, %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %esi
cmpb $0x0, -0x23(%rbp)
setne %al
xorb $-0x1, %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
addl %eax, %esi
cmpb $0x0, -0x22(%rbp)
setne %al
xorb $-0x1, %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
addl %eax, %esi
cmpb $0x0, -0x21(%rbp)
setne %al
xorb $-0x1, %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
addl %eax, %esi
callq 0xc5330
movl %eax, -0x20(%rbp)
movq -0x8(%rbp), %rax
movl $0xfffd, (%rax)         # imm = 0xFFFD
movl -0x20(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nop