// File: codebrainz[P]libutfxx/utf/utf.cxx
// Function: ConvertUTF32toUTF16
ConversionResult ConvertUTF32toUTF16 (
	const UTF32** sourceStart, const UTF32* sourceEnd,
	UTF16** targetStart, UTF16* targetEnd, ConversionFlags flags) {
	ConversionResult result = conversionOK;
	const UTF32* source = *sourceStart;
	UTF16* 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
movq %rsp, %rbp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movl $0x0, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x10(%rbp), %rax
jae 0x6c7e
movq -0x38(%rbp), %rax
cmpq -0x20(%rbp), %rax
jb 0x6b59
movl $0x2, -0x28(%rbp)
jmp 0x6c7e
movq -0x30(%rbp), %rax
movq %rax, %rcx
addq $0x4, %rcx
movq %rcx, -0x30(%rbp)
movl (%rax), %eax
movl %eax, -0x3c(%rbp)
cmpl $0xffff, -0x3c(%rbp)    # imm = 0xFFFF
ja 0x6bd9
cmpl $0xd800, -0x3c(%rbp)    # imm = 0xD800
jb 0x6bbc
cmpl $0xdfff, -0x3c(%rbp)    # imm = 0xDFFF
ja 0x6bbc
cmpl $0x0, -0x24(%rbp)
jne 0x6ba6
movq -0x30(%rbp), %rax
addq $-0x4, %rax
movq %rax, -0x30(%rbp)
movl $0x3, -0x28(%rbp)
jmp 0x6c7e
movq -0x38(%rbp), %rax
movq %rax, %rcx
addq $0x2, %rcx
movq %rcx, -0x38(%rbp)
movw $0xfffd, (%rax)         # imm = 0xFFFD
jmp 0x6bd4
movl -0x3c(%rbp), %eax
movw %ax, %cx
movq -0x38(%rbp), %rax
movq %rax, %rdx
addq $0x2, %rdx
movq %rdx, -0x38(%rbp)
movw %cx, (%rax)
jmp 0x6c79
cmpl $0x10ffff, -0x3c(%rbp)  # imm = 0x10FFFF
jbe 0x6c07
cmpl $0x0, -0x24(%rbp)
jne 0x6bf1
movl $0x3, -0x28(%rbp)
jmp 0x6c05
movq -0x38(%rbp), %rax
movq %rax, %rcx
addq $0x2, %rcx
movq %rcx, -0x38(%rbp)
movw $0xfffd, (%rax)         # imm = 0xFFFD
jmp 0x6c77
movq -0x38(%rbp), %rax
addq $0x2, %rax
cmpq -0x20(%rbp), %rax
jb 0x6c2a
movq -0x30(%rbp), %rax
addq $-0x4, %rax
movq %rax, -0x30(%rbp)
movl $0x2, -0x28(%rbp)
jmp 0x6c7e
movl -0x3c(%rbp), %eax
subl $0x10000, %eax          # imm = 0x10000
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
shrl $0xa, %eax
addl $0xd800, %eax           # imm = 0xD800
movw %ax, %cx
movq -0x38(%rbp), %rax
movq %rax, %rdx
addq $0x2, %rdx
movq %rdx, -0x38(%rbp)
movw %cx, (%rax)
movl -0x3c(%rbp), %eax
andl $0x3ff, %eax            # imm = 0x3FF
addl $0xdc00, %eax           # imm = 0xDC00
movw %ax, %cx
movq -0x38(%rbp), %rax
movq %rax, %rdx
addq $0x2, %rdx
movq %rdx, -0x38(%rbp)
movw %cx, (%rax)
jmp 0x6c79
jmp 0x6b35
movq -0x30(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, (%rax)
movq -0x38(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
movl -0x28(%rbp), %eax
popq %rbp
retq
nopl (%rax)