// File: /workspace/github_cpp_makefile_star2_O1/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 %rbx
movq (%rdi), %r10
movq (%rdx), %r9
xorl %r11d, %r11d
cmpq %rsi, %r10
jae 0xf907
movl $0x2, %eax
cmpq %rcx, %r9
jae 0xf8f0
leaq 0x4(%r10), %rbx
movl (%r10), %r14d
cmpl $0xffff, %r14d          # imm = 0xFFFF
ja 0xf886
movl %r14d, %eax
andl $0xf800, %eax           # imm = 0xF800
cmpl $0xd800, %eax           # imm = 0xD800
jne 0xf8a3
testl %r8d, %r8d
je 0xf8eb
movw $0xfffd, (%r9)          # imm = 0xFFFD
jmp 0xf8a7
cmpl $0x110000, %r14d        # imm = 0x110000
jb 0xf8ad
movb $0x1, %bpl
testl %r8d, %r8d
je 0xf900
movw $0xfffd, (%r9)          # imm = 0xFFFD
addq $0x2, %r9
jmp 0xf8e3
movw %r14w, (%r9)
addq $0x2, %r9
jmp 0xf8e0
leaq 0x2(%r9), %r15
cmpq %rcx, %r15
jae 0xf8f0
leal 0x3ff0000(%r14), %eax
shrl $0xa, %eax
addl $0xffffd800, %eax       # imm = 0xFFFFD800
movw %ax, (%r9)
andl $0x3ff, %r14d           # imm = 0x3FF
orl $0xdc00, %r14d          # imm = 0xDC00
movw %r14w, 0x2(%r9)
addq $0x4, %r9
movb $0x1, %bpl
movl %r11d, %eax
movq %rbx, %r10
jmp 0xf8f2
movl $0x3, %eax
xorl %ebp, %ebp
movl %eax, %r11d
testb %bpl, %bpl
jne 0xf843
jmp 0xf90a
movl $0x3, %eax
jmp 0xf8e6
movl %r11d, %eax
movq %r10, (%rdi)
movq %r9, (%rdx)
popq %rbx
popq %r14
popq %r15
popq %rbp
retq