// File: /workspace/github_cpp_makefile_star2_O3/codebrainz[P]libutfxx/utf/utf.cxx
// Function: ConvertUTF8toUTF32
ConversionResult ConvertUTF8toUTF32 (
	const UTF8** sourceStart, const UTF8* sourceEnd,
	UTF32** targetStart, UTF32* targetEnd, ConversionFlags flags) {
	ConversionResult result = conversionOK;
	const UTF8* source = *sourceStart;
	UTF32* 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;
		case 4: ch += *source++; ch <<= 6;
		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 the source pointer! */
		result = targetExhausted; break;
	}
	if (ch <= UNI_MAX_LEGAL_UTF32) {
		/*
		 * UTF-16 surrogate values are illegal in UTF-32, and anything
		 * over Plane 17 (> 0x10FFFF) is illegal.
		 */
		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++ = ch;
		}
	} else { /* i.e., ch > UNI_MAX_LEGAL_UTF32 */
		result = sourceIllegal;
		*target++ = UNI_REPLACEMENT_CHAR;
	}
	}
	*sourceStart = source;
	*targetStart = target;
	return result;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq (%rdi), %r9
movq %rdx, -0x8(%rsp)
movq (%rdx), %r10
xorl %eax, %eax
cmpq %rsi, %r9
jae 0x3a87
xorl %eax, %eax
movl $0xff, %r11d
leaq 0x2689(%rip), %rdx      # 0x6030
leaq 0x2782(%rip), %rbx      # 0x6130
movl $0xfffd, %r14d          # imm = 0xFFFD
movsbq (%r9), %r13
movsbq (%r13,%rdx), %r12
movzwl %r12w, %r15d
leaq (%r9,%r15), %rbp
cmpq %rsi, %rbp
jae 0x3a68
andl %r11d, %r12d
je 0x3a08
cmpl $0x1, %r12d
jne 0x3a82
movl %r13d, %r12d
andl %r11d, %r12d
cmpl $0xf4, %r12d
je 0x39fa
cmpl $0xed, %r12d
jne 0x3a82
movl %r13d, %r12d
shll $0x6, %r12d
movb 0x1(%r9), %r13b
incq %r9
incq %r9
cmpq %rcx, %r10
jae 0x3a6f
movsbl %r13b, %ebp
addl %ebp, %r12d
subl (%rbx,%r15,4), %r12d
cmpl $0x10ffff, %r12d        # imm = 0x10FFFF
ja 0x3a4b
testl %r8d, %r8d
setne %bpl
movl %r12d, %r13d
andl $0x1ff800, %r13d        # imm = 0x1FF800
cmpl $0xd800, %r13d          # imm = 0xD800
setne %r13b
cmovel %r14d, %r12d
orb %bpl, %r13b
jne 0x3a56
jmp 0x3a7c
movl $0x3, %eax
movl $0xfffd, %r12d          # imm = 0xFFFD
movl %r12d, (%r10)
addq $0x4, %r10
cmpq %rsi, %r9
jb 0x39b4
jmp 0x3a87
movl $0x1, %eax
jmp 0x3a87
notq %r15
addq %r15, %r9
movl $0x2, %eax
jmp 0x3a87
notq %r15
addq %r15, %r9
movl $0x3, %eax
movq %r9, (%rdi)
movq -0x8(%rsp), %rcx
movq %r10, (%rcx)
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq