// File: /workspace/github_c_makefile_star2_O0/MikeGray-APH[P]LibLouisAPH/source/utf-convert.c
// Function: utf16_convert_to_utf8
int utf16_convert_to_utf8(char *cchars, const int cchars_max, const unichar *uchars, const int uchars_len, int *uchars_crs)
{
	uint32_t uchar32;
	int crs, i;

	crs = 0;
	for(i = 0; i < uchars_len; i++)
	{
		if(uchars[i] == 0)
			break;

		uchar32 = uchars[i];
		if(uchar32 >= 0xd800 && uchar32 <= 0xdbff)
		{
			if(i + 1 >= uchars_len)
				break;
			i++;
			if(uchars[i] >= 0xdc00 && uchars[i] <= 0xdfff)
				uchar32  = ((uchar32 - 0xd800) << 10) + (uchars[i] - 0xdc00) + 0x10000;
			else
			{
				i--;
				break;
			}
		}

		if(uchar32 < 0x80)
		{
			if(crs > cchars_max - 2)
				break;
			cchars[crs++] = (char)uchar32 & 0x7f;
		}
		else if(uchar32 < 0x800)
		{
			if(crs > cchars_max - 3)
				break;
			cchars[crs++] = ((uchar32 >> 6) & 0x1f) | 0xc0;
			cchars[crs++] = ((uchar32 >> 0) & 0x3f) | 0x80;
		}
		else if(uchar32 < 0x10000)
		{
			if(crs > cchars_max - 4)
				break;
			cchars[crs++] = ((uchar32 >> 12) & 0x0f) | 0xe0;
			cchars[crs++] = ((uchar32 >>  6) & 0x3f) | 0x80;
			cchars[crs++] = ((uchar32 >>  0) & 0x3f) | 0x80;
		}
		else if(uchar32 < 0x110000)
		{
			if(crs > cchars_max - 5)
				break;
			cchars[crs++] = ((uchar32 >> 18) & 0x07) | 0xf0;
			cchars[crs++] = ((uchar32 >> 12) & 0x3f) | 0x80;
			cchars[crs++] = ((uchar32 >>  6) & 0x3f) | 0x80;
			cchars[crs++] = ((uchar32 >>  0) & 0x3f) | 0x80;
		}
		else
			break;
	}

	ASSERT(crs < cchars_max)
	cchars[crs] = 0;

	if(uchars_crs)
	{
		*uchars_crs = i;

		for( ; i < uchars_len; i++)
		{
			if(uchars[i] == 0)
				break;

			uchar32 = uchars[i];
			if(uchar32 >= 0xd800 && uchar32 <= 0xdbff)
			{
				if(i + 1 >= uchars_len)
					break;
				i++;
				if(uchars[i] >= 0xdc00 && uchars[i] <= 0xdfff)
					uchar32  = ((uchar32 - 0xd800) * 0x400) + (uchars[i] - 0xdc00) + 0x10000;
				else
					break;
			}
			     if(uchar32 < 0x80)
				crs += 1;
			else if(uchar32 < 0x800)
				crs += 2;
			else if(uchar32 < 0x10000)
				crs += 3;
			else if(uchar32 < 0x110000)
				crs += 4;
			else
				break;
		}
	}

	return crs;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq %r8, -0x28(%rbp)
movl $0x0, -0x30(%rbp)
movl $0x0, -0x34(%rbp)
movl -0x34(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x1da1
movq -0x18(%rbp), %rax
movslq -0x34(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
cmpl $0x0, %eax
jne 0x1afa
jmp 0x1da1
movq -0x18(%rbp), %rax
movslq -0x34(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
movl %eax, -0x2c(%rbp)
cmpl $0xd800, -0x2c(%rbp)    # imm = 0xD800
jb 0x1b97
cmpl $0xdbff, -0x2c(%rbp)    # imm = 0xDBFF
ja 0x1b97
movl -0x34(%rbp), %eax
addl $0x1, %eax
cmpl -0x1c(%rbp), %eax
jl 0x1b2f
jmp 0x1da1
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
movq -0x18(%rbp), %rax
movslq -0x34(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
cmpl $0xdc00, %eax           # imm = 0xDC00
jl 0x1b87
movq -0x18(%rbp), %rax
movslq -0x34(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
cmpl $0xdfff, %eax           # imm = 0xDFFF
jg 0x1b87
movl -0x2c(%rbp), %eax
subl $0xd800, %eax           # imm = 0xD800
shll $0xa, %eax
movq -0x18(%rbp), %rcx
movslq -0x34(%rbp), %rdx
movzwl (%rcx,%rdx,2), %ecx
subl $0xdc00, %ecx           # imm = 0xDC00
addl %ecx, %eax
addl $0x10000, %eax          # imm = 0x10000
movl %eax, -0x2c(%rbp)
jmp 0x1b95
movl -0x34(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x1da1
jmp 0x1b97
cmpl $0x80, -0x2c(%rbp)
jae 0x1bd7
movl -0x30(%rbp), %eax
movl -0xc(%rbp), %ecx
subl $0x2, %ecx
cmpl %ecx, %eax
jle 0x1bb2
jmp 0x1da1
movl -0x2c(%rbp), %eax
movsbl %al, %eax
andl $0x7f, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movl -0x30(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x30(%rbp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
jmp 0x1d91
cmpl $0x800, -0x2c(%rbp)     # imm = 0x800
jae 0x1c41
movl -0x30(%rbp), %eax
movl -0xc(%rbp), %ecx
subl $0x3, %ecx
cmpl %ecx, %eax
jle 0x1bf2
jmp 0x1da1
movl -0x2c(%rbp), %eax
shrl $0x6, %eax
andl $0x1f, %eax
orl $0xc0, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movl -0x30(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x30(%rbp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl -0x2c(%rbp), %eax
shrl $0x0, %eax
andl $0x3f, %eax
orl $0x80, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movl -0x30(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x30(%rbp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
jmp 0x1d8f
cmpl $0x10000, -0x2c(%rbp)   # imm = 0x10000
jae 0x1cd4
movl -0x30(%rbp), %eax
movl -0xc(%rbp), %ecx
subl $0x4, %ecx
cmpl %ecx, %eax
jle 0x1c60
jmp 0x1da1
movl -0x2c(%rbp), %eax
shrl $0xc, %eax
andl $0xf, %eax
orl $0xe0, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movl -0x30(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x30(%rbp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl -0x2c(%rbp), %eax
shrl $0x6, %eax
andl $0x3f, %eax
orl $0x80, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movl -0x30(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x30(%rbp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl -0x2c(%rbp), %eax
shrl $0x0, %eax
andl $0x3f, %eax
orl $0x80, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movl -0x30(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x30(%rbp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
jmp 0x1d8d
cmpl $0x110000, -0x2c(%rbp)  # imm = 0x110000
jae 0x1d89
movl -0x30(%rbp), %eax
movl -0xc(%rbp), %ecx
subl $0x5, %ecx
cmpl %ecx, %eax
jle 0x1cf3
jmp 0x1da1
movl -0x2c(%rbp), %eax
shrl $0x12, %eax
andl $0x7, %eax
orl $0xf0, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movl -0x30(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x30(%rbp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl -0x2c(%rbp), %eax
shrl $0xc, %eax
andl $0x3f, %eax
orl $0x80, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movl -0x30(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x30(%rbp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl -0x2c(%rbp), %eax
shrl $0x6, %eax
andl $0x3f, %eax
orl $0x80, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movl -0x30(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x30(%rbp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl -0x2c(%rbp), %eax
shrl $0x0, %eax
andl $0x3f, %eax
orl $0x80, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movl -0x30(%rbp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, -0x30(%rbp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
jmp 0x1d8b
jmp 0x1da1
jmp 0x1d8d
jmp 0x1d8f
jmp 0x1d91
jmp 0x1d93
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x1ad8
movl -0x30(%rbp), %eax
cmpl -0xc(%rbp), %eax
jl 0x1dae
callq 0x1050
movq -0x8(%rbp), %rax
movslq -0x30(%rbp), %rcx
movb $0x0, (%rax,%rcx)
cmpq $0x0, -0x28(%rbp)
je 0x1ee7
movl -0x34(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
movl -0x34(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jge 0x1ee5
movq -0x18(%rbp), %rax
movslq -0x34(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
cmpl $0x0, %eax
jne 0x1df0
jmp 0x1ee5
movq -0x18(%rbp), %rax
movslq -0x34(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
movl %eax, -0x2c(%rbp)
cmpl $0xd800, -0x2c(%rbp)    # imm = 0xD800
jb 0x1e7d
cmpl $0xdbff, -0x2c(%rbp)    # imm = 0xDBFF
ja 0x1e7d
movl -0x34(%rbp), %eax
addl $0x1, %eax
cmpl -0x1c(%rbp), %eax
jl 0x1e21
jmp 0x1ee5
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
movq -0x18(%rbp), %rax
movslq -0x34(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
cmpl $0xdc00, %eax           # imm = 0xDC00
jl 0x1e79
movq -0x18(%rbp), %rax
movslq -0x34(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
cmpl $0xdfff, %eax           # imm = 0xDFFF
jg 0x1e79
movl -0x2c(%rbp), %eax
subl $0xd800, %eax           # imm = 0xD800
shll $0xa, %eax
movq -0x18(%rbp), %rcx
movslq -0x34(%rbp), %rdx
movzwl (%rcx,%rdx,2), %ecx
subl $0xdc00, %ecx           # imm = 0xDC00
addl %ecx, %eax
addl $0x10000, %eax          # imm = 0x10000
movl %eax, -0x2c(%rbp)
jmp 0x1e7b
jmp 0x1ee5
jmp 0x1e7d
cmpl $0x80, -0x2c(%rbp)
jae 0x1e91
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x1ed5
cmpl $0x800, -0x2c(%rbp)     # imm = 0x800
jae 0x1ea5
movl -0x30(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x30(%rbp)
jmp 0x1ed3
cmpl $0x10000, -0x2c(%rbp)   # imm = 0x10000
jae 0x1eb9
movl -0x30(%rbp), %eax
addl $0x3, %eax
movl %eax, -0x30(%rbp)
jmp 0x1ed1
cmpl $0x110000, -0x2c(%rbp)  # imm = 0x110000
jae 0x1ecd
movl -0x30(%rbp), %eax
addl $0x4, %eax
movl %eax, -0x30(%rbp)
jmp 0x1ecf
jmp 0x1ee5
jmp 0x1ed1
jmp 0x1ed3
jmp 0x1ed5
jmp 0x1ed7
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x1dce
jmp 0x1ee7
movl -0x30(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq