// File: /workspace/github_cpp_makefile_star2_O3/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, %rbx
cmpq %rdx, %rdi
je 0x137fc
addq %rdx, %rcx
movq %rbx, %r9
subq %rdx, %r9
leaq (%rdi,%r9), %rax
cmpq %rcx, %rbx
setae %r10b
cmpq %rsi, %r9
setge %r9b
orb %r10b, %r9b
jne 0x13853
addq %rdi, %rsi
leaq 0x5127(%rip), %r9       # 0x18770
leaq 0x5140(%rip), %r10      # 0x18790
leaq 0x1(%rbx), %r11
movb (%rbx), %r15b
testb %r15b, %r15b
js 0x13667
movb %r15b, (%rax)
incq %rax
jmp 0x137e9
cmpb $-0x40, %r15b
jb 0x137e9
movzbl %r15b, %r14d
cmpb $-0x20, %r15b
jb 0x136df
cmpb $-0x10, %r15b
jb 0x136f7
cmpb $-0x8, %r15b
jb 0x13710
cmpb $-0x4, %r15b
jb 0x13726
cmpb $-0x3, %r15b
ja 0x137e9
movq %rcx, %r15
subq %r11, %r15
cmpq $0x5, %r15
jl 0x13850
movzbl (%r11), %r15d
movl %r15d, %r12d
andl $-0x40, %r12d
cmpl $0x80, %r12d
jne 0x137e9
addq $0x2, %rbx
shll $0x6, %r14d
andl $0x40, %r14d
andl $0x3f, %r15d
orl %r14d, %r15d
movq %rbx, %r11
jmp 0x1373d
movq %rcx, %rbx
subq %r11, %rbx
testq %rbx, %rbx
jle 0x13850
andl $0x1f, %r14d
jmp 0x137a3
movq %rcx, %rbx
subq %r11, %rbx
cmpq $0x2, %rbx
jl 0x13850
andl $0xf, %r14d
movl %r14d, %ebx
jmp 0x13782
movq %rcx, %rbx
subq %r11, %rbx
cmpq $0x3, %rbx
jl 0x13850
andl $0x7, %r14d
jmp 0x13761
movq %rcx, %rbx
subq %r11, %rbx
cmpq $0x4, %rbx
jl 0x13850
andl $0x3, %r14d
movl %r14d, %r15d
movzbl (%r11), %r14d
movl %r14d, %ebx
andl $-0x40, %ebx
cmpl $0x80, %ebx
jne 0x137e9
incq %r11
shll $0x6, %r15d
andl $0x3f, %r14d
orl %r15d, %r14d
movzbl (%r11), %ebx
movl %ebx, %r15d
andl $-0x40, %r15d
cmpl $0x80, %r15d
jne 0x137e9
incq %r11
shll $0x6, %r14d
andl $0x3f, %ebx
orl %r14d, %ebx
movzbl (%r11), %r14d
movl %r14d, %r15d
andl $-0x40, %r15d
cmpl $0x80, %r15d
jne 0x137e9
incq %r11
shll $0x6, %ebx
andl $0x3f, %r14d
orl %ebx, %r14d
movzbl (%r11), %ebx
movl %ebx, %r15d
andl $-0x40, %r15d
cmpl $0x80, %r15d
jne 0x137e9
incq %r11
cmpl $0x1f, %r14d
ja 0x137e9
movl %r14d, %r15d
shll $0x6, %r15d
andl $0x3f, %ebx
andl $-0x4, %r14d
movslq (%r14,%r9), %r14
movzbl %r15b, %r15d
orq %rbx, %r15
addq %r14, %r15
movb (%r10,%r15), %r15b
testb %r15b, %r15b
jne 0x1365c
movq %r11, %rbx
cmpq %rcx, %r11
jae 0x13853
cmpq %rsi, %rax
jb 0x13650
jmp 0x13853
cmpq %rcx, %rsi
movq %rcx, %rax
cmovbq %rsi, %rax
cltq
movq %rax, %r9
movq %rdx, %rbx
andq $-0x4, %r9
jle 0x1382f
addq %rdx, %r9
movq %rdx, %rbx
testl $0x80808080, (%rbx)     # imm = 0x80808080
jne 0x1361b
addq $0x4, %rbx
cmpq %r9, %rbx
jb 0x1381a
leaq (%rdx,%rax), %r9
cmpq %r9, %rbx
jae 0x13846
cmpb $0x0, (%rbx)
js 0x1361b
incq %rbx
jmp 0x13833
testq %r8, %r8
je 0x13861
addq %rax, (%r8)
jmp 0x13861
movq %r11, %rbx
testq %r8, %r8
je 0x1385e
subq %rdx, %rbx
addq %rbx, (%r8)
subq %rdi, %rax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq