// File: /workspace/github_c_makefile_star2_O3/lb3361[P]dosfs/ff.c
// Function: put_utf
static BYTE put_utf (	/* Returns number of encoding units written (0:buffer overflow or wrong encoding) */
	DWORD chr,	/* UTF-16 encoded character (Surrogate pair if >=0x10000) */
	TCHAR* buf,	/* Output buffer */
	UINT szb	/* Size of the buffer */
)
{
#if FF_LFN_UNICODE == 1	/* UTF-16 output */
	WCHAR hs, wc;

	hs = (WCHAR)(chr >> 16);
	wc = (WCHAR)chr;
	if (hs == 0) {	/* Single encoding unit? */
		if (szb < 1 || IsSurrogate(wc)) return 0;	/* Buffer overflow or wrong code? */
		*buf = wc;
		return 1;
	}
	if (szb < 2 || !IsSurrogateH(hs) || !IsSurrogateL(wc)) return 0;	/* Buffer overflow or wrong surrogate? */
	*buf++ = hs;
	*buf++ = wc;
	return 2;

#elif FF_LFN_UNICODE == 2	/* UTF-8 output */
	DWORD hc;

	if (chr < 0x80) {	/* Single byte code? */
		if (szb < 1) return 0;	/* Buffer overflow? */
		*buf = (TCHAR)chr;
		return 1;
	}
	if (chr < 0x800) {	/* 2-byte sequence? */
		if (szb < 2) return 0;	/* Buffer overflow? */
		*buf++ = (TCHAR)(0xC0 | (chr >> 6 & 0x1F));
		*buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F));
		return 2;
	}
	if (chr < 0x10000) {	/* 3-byte sequence? */
		if (szb < 3 || IsSurrogate(chr)) return 0;	/* Buffer overflow or wrong code? */
		*buf++ = (TCHAR)(0xE0 | (chr >> 12 & 0x0F));
		*buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F));
		*buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F));
		return 3;
	}
	/* 4-byte sequence */
	if (szb < 4) return 0;	/* Buffer overflow? */
	hc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6;	/* Get high 10 bits */
	chr = (chr & 0xFFFF) - 0xDC00;					/* Get low 10 bits */
	if (hc >= 0x100000 || chr >= 0x400) return 0;	/* Wrong surrogate? */
	chr = (hc | chr) + 0x10000;
	*buf++ = (TCHAR)(0xF0 | (chr >> 18 & 0x07));
	*buf++ = (TCHAR)(0x80 | (chr >> 12 & 0x3F));
	*buf++ = (TCHAR)(0x80 | (chr >> 6 & 0x3F));
	*buf++ = (TCHAR)(0x80 | (chr >> 0 & 0x3F));
	return 4;

#elif FF_LFN_UNICODE == 3	/* UTF-32 output */
	DWORD hc;

	if (szb < 1) return 0;	/* Buffer overflow? */
	if (chr >= 0x10000) {	/* Out of BMP? */
		hc = ((chr & 0xFFFF0000) - 0xD8000000) >> 6;	/* Get high 10 bits */
		chr = (chr & 0xFFFF) - 0xDC00;					/* Get low 10 bits */
		if (hc >= 0x100000 || chr >= 0x400) return 0;	/* Wrong surrogate? */
		chr = (hc | chr) + 0x10000;
	}
	*buf++ = (TCHAR)chr;
	return 1;

#else						/* ANSI/OEM output */
	WCHAR wc;

	wc = ff_uni2oem(chr, CODEPAGE);
	if (wc >= 0x100) {	/* Is this a DBC? */
		if (szb < 2) return 0;
		*buf++ = (char)(wc >> 8);	/* Store DBC 1st byte */
		*buf++ = (TCHAR)wc;			/* Store DBC 2nd byte */
		return 2;
	}
	if (wc == 0 || szb < 1) return 0;	/* Invalid char or buffer overflow? */
	*buf++ = (TCHAR)wc;					/* Store the character */
	return 1;
#endif
}

// Assembly:
cmpl $0x7f, %edi
ja 0x8c87
testl %edx, %edx
je 0x8d28
movb %dil, (%rsi)
movb $0x1, %al
retq
cmpl $0x7ff, %edi            # imm = 0x7FF
ja 0x8cb0
cmpl $0x2, %edx
jb 0x8d28
movl %edi, %eax
shrl $0x6, %eax
orb $-0x40, %al
movb %al, (%rsi)
andb $0x3f, %dil
orb $-0x80, %dil
movb %dil, 0x1(%rsi)
movb $0x2, %al
retq
cmpl $0xffff, %edi           # imm = 0xFFFF
ja 0x8cf7
cmpl $0x3, %edx
setb %al
movl %edi, %ecx
andl $0xf800, %ecx           # imm = 0xF800
cmpl $0xd800, %ecx           # imm = 0xD800
sete %cl
orb %al, %cl
jne 0x8d28
movl %edi, %eax
shrl $0xc, %eax
orb $-0x20, %al
movb %al, (%rsi)
movl %edi, %eax
shrl $0x6, %eax
andb $0x3f, %al
orb $-0x80, %al
movb %al, 0x1(%rsi)
andb $0x3f, %dil
orb $-0x80, %dil
movb %dil, 0x2(%rsi)
movb $0x3, %al
retq
cmpl $0x4, %edx
jb 0x8d28
movl %edi, %eax
andl $0xffff0000, %eax       # imm = 0xFFFF0000
addl $0x28000000, %eax       # imm = 0x28000000
movzwl %di, %ecx
addl $0xffff2400, %ecx       # imm = 0xFFFF2400
cmpl $0x3ffffc1, %eax        # imm = 0x3FFFFC1
setae %dl
cmpl $0x400, %ecx            # imm = 0x400
setae %r8b
orb %dl, %r8b
je 0x8d2b
xorl %eax, %eax
retq
shrl $0x6, %eax
movl %eax, %edx
orl %ecx, %edx
addl %ecx, %eax
addl $0x10000, %eax          # imm = 0x10000
movl %eax, %ecx
shrl $0x12, %ecx
orb $-0x10, %cl
movb %cl, (%rsi)
shrl $0xc, %eax
andb $0x3f, %al
orb $-0x80, %al
movb %al, 0x1(%rsi)
shrl $0x6, %edx
andb $0x3f, %dl
orb $-0x80, %dl
movb %dl, 0x2(%rsi)
andb $0x3f, %dil
orb $-0x80, %dil
movb %dil, 0x3(%rsi)
movb $0x4, %al
retq