// File: /workspace/github_cpp_makefile_star2_O2/Fohlen[P]cubescript-standalone/stream.cpp
// Function: decodeutf8(unsigned char*, unsigned long, unsigned char const*, unsigned long, unsigned long*)
size_t decodeutf8(uchar *dstbuf, size_t dstlen, const uchar *srcbuf, size_t srclen, size_t *carry)
{
    uchar *dst = dstbuf, *dstend = &dstbuf[dstlen];
    const uchar *src = srcbuf, *srcend = &srcbuf[srclen];
    if(dstbuf == srcbuf)
    {
        int len = min(dstlen, srclen);
        for(const uchar *end4 = &srcbuf[len&~3]; src < end4; src += 4) if(*(const int *)src & 0x80808080) goto decode;
        for(const uchar *end = &srcbuf[len]; src < end; src++) if(*src & 0x80) goto decode;
        if(carry) *carry += len;
        return len;
    }

decode:
    dst += src - srcbuf;
    while(src < srcend && dst < dstend)
    {
        int c = *src++;
        if(c < 0x80) *dst++ = c;
        else if(c >= 0xC0)
        {
            int uni;
            if(c >= 0xE0)
            {
                if(c >= 0xF0)
                {
                    if(c >= 0xF8)
                    {
                        if(c >= 0xFC)
                        {
                            if(c >= 0xFE) continue;
                            uni = c&1; if(srcend - src < 5) break;
                            c = *src; if((c&0xC0) != 0x80) continue; src++; uni = (uni<<6) | (c&0x3F);
                        }
                        else { uni = c&3; if(srcend - src < 4) break; }
                        c = *src; if((c&0xC0) != 0x80) continue; src++; uni = (uni<<6) | (c&0x3F);
                    }
                    else { uni = c&7; if(srcend - src < 3) break; }
                    c = *src; if((c&0xC0) != 0x80) continue; src++; uni = (uni<<6) | (c&0x3F);
                }
                else { uni = c&0xF; if(srcend - src < 2) break; }
                c = *src; if((c&0xC0) != 0x80) continue; src++; uni = (uni<<6) | (c&0x3F);
            }
            else { uni = c&0x1F; if(srcend - src < 1) break; }
            c = *src; if((c&0xC0) != 0x80) continue; src++; uni = (uni<<6) | (c&0x3F);
            c = uni2cube(uni);
            if(!c) continue;
            *dst++ = c;
        }
    }
    if(carry) *carry += src - srcbuf;
    return dst - dstbuf;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rdx, %r9
cmpq %rdx, %rdi
je 0xde26
addq %rdi, %rsi
addq %rdx, %rcx
movq %r9, %rax
subq %rdx, %rax
addq %rdi, %rax
leaq 0x459b(%rip), %r10      # 0x12210
leaq 0x45b4(%rip), %r11      # 0x12230
movq %r9, %r14
cmpq %rcx, %r9
jae 0xde72
cmpq %rsi, %rax
jae 0xde72
leaq 0x1(%r14), %r9
movb (%r14), %r15b
testb %r15b, %r15b
js 0xdca5
movb %r15b, (%rax)
incq %rax
jmp 0xdc7c
cmpb $-0x40, %r15b
jb 0xdc7c
movzbl %r15b, %ebx
cmpb $-0x20, %r15b
jb 0xdd0b
cmpb $-0x10, %r15b
jb 0xdd22
cmpb $-0x8, %r15b
jb 0xdd3a
cmpb $-0x4, %r15b
jb 0xdd4f
cmpb $-0x3, %r15b
ja 0xdc7c
movq %rcx, %r15
subq %r9, %r15
cmpq $0x5, %r15
jl 0xde6f
movzbl (%r9), %r15d
movl %r15d, %r12d
andl $-0x40, %r12d
cmpl $0x80, %r12d
jne 0xdc7c
addq $0x2, %r14
shll $0x6, %ebx
andl $0x40, %ebx
andl $0x3f, %r15d
orl %ebx, %r15d
movq %r14, %r9
jmp 0xdd65
movq %rcx, %r14
subq %r9, %r14
testq %r14, %r14
jle 0xde6f
andl $0x1f, %ebx
jmp 0xddd4
movq %rcx, %r14
subq %r9, %r14
cmpq $0x2, %r14
jl 0xde6f
andl $0xf, %ebx
movl %ebx, %r14d
jmp 0xddaf
movq %rcx, %r14
subq %r9, %r14
cmpq $0x3, %r14
jl 0xde6f
andl $0x7, %ebx
jmp 0xdd8a
movq %rcx, %r14
subq %r9, %r14
cmpq $0x4, %r14
jl 0xde6f
andl $0x3, %ebx
movl %ebx, %r15d
movzbl (%r9), %ebx
movl %ebx, %r14d
andl $-0x40, %r14d
cmpl $0x80, %r14d
jne 0xdc7c
incq %r9
shll $0x6, %r15d
andl $0x3f, %ebx
orl %r15d, %ebx
movzbl (%r9), %r14d
movl %r14d, %r15d
andl $-0x40, %r15d
cmpl $0x80, %r15d
jne 0xdc7c
incq %r9
shll $0x6, %ebx
andl $0x3f, %r14d
orl %ebx, %r14d
movzbl (%r9), %ebx
movl %ebx, %r15d
andl $-0x40, %r15d
cmpl $0x80, %r15d
jne 0xdc7c
incq %r9
shll $0x6, %r14d
andl $0x3f, %ebx
orl %r14d, %ebx
movzbl (%r9), %r14d
movl %r14d, %r15d
andl $-0x40, %r15d
cmpl $0x80, %r15d
jne 0xdc7c
incq %r9
cmpl $0x1f, %ebx
ja 0xdc7c
movl %ebx, %r15d
shll $0x6, %r15d
andl $0x3f, %r14d
andl $-0x4, %ebx
movslq (%rbx,%r10), %rbx
movzbl %r15b, %r15d
orq %r14, %r15
addq %rbx, %r15
movb (%r11,%r15), %r15b
testb %r15b, %r15b
jne 0xdc9d
jmp 0xdc7c
cmpq %rcx, %rsi
movq %rcx, %rax
cmovbq %rsi, %rax
cltq
movq %rax, %r10
andq $-0x4, %r10
addq %rdx, %r10
movq %rdx, %r9
cmpq %r10, %r9
jae 0xde57
testl $0x80808080, (%r9)      # imm = 0x80808080
jne 0xdc5f
addq $0x4, %r9
jmp 0xde3f
leaq (%rdx,%rax), %r10
cmpq %r10, %r9
jae 0xde89
cmpb $0x0, (%r9)
js 0xdc5f
incq %r9
jmp 0xde5b
movq %r9, %r14
testq %r8, %r8
je 0xde7d
subq %rdx, %r14
addq %r14, (%r8)
subq %rdi, %rax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
testq %r8, %r8
je 0xde80
addq %rax, (%r8)
jmp 0xde80