// File: /workspace/github_cpp_makefile_star2_O3/codebrainz[P]libutfxx/utf/utf.cxx
// Function: ConvertUTF8toUTF16
ConversionResult ConvertUTF8toUTF16 (
	const UTF8** sourceStart, const UTF8* sourceEnd,
	UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
	ConversionResult result = conversionOK;
	const UTF8* source = *sourceStart;
	UTF16* target = *targetStart;
	while (source < sourceEnd) {
	UTF32 ch = 0;
	unsigned short extraBytesToRead = trailingBytesForUTF8[*source];
	if (source + extraBytesToRead >= sourceEnd) {
		result = sourceExhausted; break;
	}
	/* Do this check whether lenient or strict */
	if (! isLegalUTF8(source, extraBytesToRead+1)) {
		result = sourceIllegal;
		break;
	}
	/*
	 * The cases all fall through. See "Note A" below.
	 */
	switch (extraBytesToRead) {
		case 5: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
		case 4: ch += *source++; ch <<= 6; /* remember, illegal UTF-8 */
		case 3: ch += *source++; ch <<= 6;
		case 2: ch += *source++; ch <<= 6;
		case 1: ch += *source++; ch <<= 6;
		case 0: ch += *source++;
	}
	ch -= offsetsFromUTF8[extraBytesToRead];

	if (target >= targetEnd) {
		source -= (extraBytesToRead+1); /* Back up source pointer! */
		result = targetExhausted; break;
	}
	if (ch <= UNI_MAX_BMP) { /* Target is a character <= 0xFFFF */
		/* UTF-16 surrogate values are illegal in UTF-32 */
		if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) {
		if (flags == strictConversion) {
			source -= (extraBytesToRead+1); /* 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_UTF16) {
		if (flags == strictConversion) {
		result = sourceIllegal;
		source -= (extraBytesToRead+1); /* return to the start */
		break; /* Bail out; shouldn't continue */
		} else {
		*target++ = UNI_REPLACEMENT_CHAR;
		}
	} else {
		/* target is a character in range 0xFFFF - 0x10FFFF. */
		if (target + 1 >= targetEnd) {
		source -= (extraBytesToRead+1); /* 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:
movq (%rdi), %r10
movq (%rdx), %r9
cmpq %rsi, %r10
jae 0x3814
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movl $0xff, %r11d
leaq 0x290c(%rip), %rbx      # 0x6030
leaq 0x2a05(%rip), %r14      # 0x6130
movsbq (%r10), %r13
movsbq (%r13,%rbx), %r12
movzwl %r12w, %r15d
leaq (%r10,%r15), %rax
cmpq %rsi, %rax
jae 0x3825
movl $0x3, %eax
andl %r11d, %r12d
je 0x3782
cmpl $0x1, %r12d
jne 0x3832
movl %r13d, %ebp
andl %r11d, %ebp
cmpl $0xf4, %ebp
je 0x3774
cmpl $0xed, %ebp
jne 0x3832
movl %r13d, %r12d
shll $0x6, %r12d
movb 0x1(%r10), %r13b
incq %r10
incq %r10
cmpq %rcx, %r9
jae 0x3818
movsbl %r13b, %ebp
addl %ebp, %r12d
subl (%r14,%r15,4), %r12d
cmpl $0xffff, %r12d          # imm = 0xFFFF
ja 0x37b9
movl %r12d, %ebp
andl $0xf800, %ebp           # imm = 0xF800
cmpl $0xd800, %ebp           # imm = 0xD800
je 0x37c2
movw %r12w, (%r9)
jmp 0x37cd
cmpl $0x110000, %r12d        # imm = 0x110000
jb 0x37d3
testl %r8d, %r8d
je 0x382c
movw $0xfffd, (%r9)          # imm = 0xFFFD
addq $0x2, %r9
jmp 0x3807
leaq 0x2(%r9), %rax
cmpq %rcx, %rax
jae 0x3818
leal 0x3ff0000(%r12), %eax
shrl $0xa, %eax
addl $0xffffd800, %eax       # imm = 0xFFFFD800
movw %ax, (%r9)
andl $0x3ff, %r12d           # imm = 0x3FF
orl $0xdc00, %r12d          # imm = 0xDC00
movw %r12w, 0x2(%r9)
addq $0x4, %r9
cmpq %rsi, %r10
jb 0x372b
xorl %eax, %eax
jmp 0x3832
xorl %eax, %eax
jmp 0x383c
notq %r15
addq %r15, %r10
movl $0x2, %eax
jmp 0x3832
movl $0x1, %eax
jmp 0x3832
notq %r15
addq %r15, %r10
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
movq %r10, (%rdi)
movq %r9, (%rdx)
retq