// File: /workspace/github_cpp_makefile_star2_O2/andrakis[P]alisp/contrib/linenoise-ng/src/ConvertUTF.cpp
// Function: linenoise_ng::ConvertUTF32toUTF16(unsigned int const**, unsigned int const*, char16_t**, char16_t*, linenoise_ng::ConversionFlags)
ConversionResult ConvertUTF32toUTF16 (
        const UTF32** sourceStart, const UTF32* sourceEnd, 
        char16_t** targetStart, char16_t* targetEnd, ConversionFlags flags) {
    ConversionResult result = conversionOK;
    const UTF32* source = *sourceStart;
    char16_t* target = *targetStart;
    while (source < sourceEnd) {
        UTF32 ch;
        if (target >= targetEnd) {
            result = targetExhausted; break;
        }
        ch = *source++;
        if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
            /* UTF-16 surrogate values are illegal in UTF-32; 0xffff or 0xfffe are both reserved values */
            if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
                if (flags == strictConversion) {
                    --source; /* return to the illegal value itself */
                    result = sourceIllegal;
                    break;
                } else {
                    *target++ = UNI_REPLACEMENT_CHAR;
                }
            } else {
                *target++ = (UTF16)ch; /* normal case */
            }
        } else if (ch > UNI_MAX_LEGAL_UTF32) {
            if (flags == strictConversion) {
                result = sourceIllegal;
            } else {
                *target++ = UNI_REPLACEMENT_CHAR;
            }
        } else {
            /* target is a character in range 0xFFFF - 0x10FFFF. */
            if (target + 1 >= targetEnd) {
                --source; /* Back up source pointer! */
                result = targetExhausted; break;
            }
            ch -= halfBase;
            *target++ = (UTF16)((ch >> halfShift) + UNI_SUR_HIGH_START);
            *target++ = (UTF16)((ch & halfMask) + UNI_SUR_LOW_START);
        }
    }
    *sourceStart = source;
    *targetStart = target;
    return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq (%rdi), %rbx
movq (%rdx), %r9
xorl %eax, %eax
movl $0x2, %r10d
movl $0x3, %r11d
cmpq %rsi, %rbx
jae 0xd8ec
cmpq %rcx, %r9
jae 0xd8e9
leaq 0x4(%rbx), %r14
movl (%rbx), %r15d
cmpl $0xffff, %r15d          # imm = 0xFFFF
ja 0xd87e
movl %r15d, %ebp
andl $0xf800, %ebp           # imm = 0xF800
cmpl $0xd800, %ebp           # imm = 0xD800
jne 0xd894
testl %r8d, %r8d
jne 0xd88c
jmp 0xd8fb
cmpl $0x110000, %r15d        # imm = 0x110000
jb 0xd8a1
testl %r8d, %r8d
je 0xd8dd
movw $0xfffd, (%r9)          # imm = 0xFFFD
jmp 0xd898
movw %r15w, (%r9)
addq $0x2, %r9
movq %r14, %rbx
jmp 0xd844
leaq 0x2(%r9), %r12
cmpq %rcx, %r12
jae 0xd8e9
leal 0x3ff0000(%r15), %ebx
shrl $0xa, %ebx
addl $0xffffd800, %ebx       # imm = 0xFFFFD800
movw %bx, (%r9)
andl $0x3ff, %r15d           # imm = 0x3FF
orl $0xdc00, %r15d          # imm = 0xDC00
movw %r15w, 0x2(%r9)
addq $0x4, %r9
movq %r14, %rbx
jmp 0xd844
addq $0x4, %rbx
movl %r11d, %eax
jmp 0xd844
movl %r10d, %eax
movq %rbx, (%rdi)
movq %r9, (%rdx)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movl %r11d, %eax
jmp 0xd8ec