// File: /workspace/github_c_makefile_star2_O3/uobikiemukot[P]yaft/./parse.h
// Function: utf8_charset
void utf8_charset(struct terminal_t *term, uint8_t ch)
{
	if (0x80 <= ch && ch <= 0xBF) {
		/* check illegal UTF-8 sequence
			* ? byte sequence: first byte must be between 0xC2 ~ 0xFD
			* 2 byte sequence: first byte must be between 0xC2 ~ 0xDF
			* 3 byte sequence: second byte following 0xE0 must be between 0xA0 ~ 0xBF
			* 4 byte sequence: second byte following 0xF0 must be between 0x90 ~ 0xBF
			* 5 byte sequence: second byte following 0xF8 must be between 0x88 ~ 0xBF
			* 6 byte sequence: second byte following 0xFC must be between 0x84 ~ 0xBF
		*/
		if ((term->charset.following_byte == 0)
			|| (term->charset.following_byte == 1 && term->charset.count == 0 && term->charset.code <= 1)
			|| (term->charset.following_byte == 2 && term->charset.count == 0 && term->charset.code == 0 && ch < 0xA0)
			|| (term->charset.following_byte == 3 && term->charset.count == 0 && term->charset.code == 0 && ch < 0x90)
			|| (term->charset.following_byte == 4 && term->charset.count == 0 && term->charset.code == 0 && ch < 0x88)
			|| (term->charset.following_byte == 5 && term->charset.count == 0 && term->charset.code == 0 && ch < 0x84))
			term->charset.is_valid = false;

		term->charset.code <<= 6;
		term->charset.code += ch & 0x3F;
		term->charset.count++;
	} else if (0xC0 <= ch && ch <= 0xDF) {
		term->charset.code = ch & 0x1F;
		term->charset.following_byte = 1;
		term->charset.count = 0;
		return;
	} else if (0xE0 <= ch && ch <= 0xEF) {
		term->charset.code = ch & 0x0F;
		term->charset.following_byte = 2;
		term->charset.count = 0;
		return;
	} else if (0xF0 <= ch && ch <= 0xF7) {
		term->charset.code = ch & 0x07;
		term->charset.following_byte = 3;
		term->charset.count = 0;
		return;
	} else if (0xF8 <= ch && ch <= 0xFB) {
		term->charset.code = ch & 0x03;
		term->charset.following_byte = 4;
		term->charset.count = 0;
		return;
	} else if (0xFC <= ch && ch <= 0xFD) {
		term->charset.code = ch & 0x01;
		term->charset.following_byte = 5;
		term->charset.count = 0;
		return;
	} else { /* 0xFE - 0xFF: not used in UTF-8 */
		addch(term, REPLACEMENT_CHAR);
		reset_charset(term);
		return;
	}

	if (term->charset.count >= term->charset.following_byte) {
		/*	illegal code point (ref: http://www.unicode.org/reports/tr27/tr27-4.html)
			0xD800   ~ 0xDFFF : surrogate pair
			0xFDD0   ~ 0xFDEF : noncharacter
			0xnFFFE  ~ 0xnFFFF: noncharacter (n: 0x00 ~ 0x10)
			0x110000 ~        : invalid (unicode U+0000 ~ U+10FFFF)
		*/
		if (!term->charset.is_valid
			|| (0xD800 <= term->charset.code && term->charset.code <= 0xDFFF)
			|| (0xFDD0 <= term->charset.code && term->charset.code <= 0xFDEF)
			|| ((term->charset.code & 0xFFFF) == 0xFFFE || (term->charset.code & 0xFFFF) == 0xFFFF)
			|| (term->charset.code > 0x10FFFF))
			addch(term, REPLACEMENT_CHAR);
		else
			addch(term, term->charset.code);

		reset_charset(term);
	}
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
cmpb $-0x41, %sil
jg 0x70bb
movl 0x58(%rbx), %eax
cmpq $0x5, %rax
ja 0x7150
leaq 0xfff(%rip), %rcx       # 0x8098
movslq (%rcx,%rax,4), %rdx
addq %rcx, %rdx
jmpq *%rdx
cmpl $0x0, 0x5c(%rbx)
jne 0x7150
cmpl $0x2, 0x54(%rbx)
jb 0x714c
jmp 0x7150
movl %esi, %eax
andb $-0x20, %al
cmpb $-0x40, %al
jne 0x70d6
andl $0x1f, %esi
movl %esi, 0x54(%rbx)
movq $0x1, 0x58(%rbx)
jmp 0x71d0
movl %esi, %eax
andb $-0x10, %al
cmpb $-0x20, %al
jne 0x70f1
andl $0xf, %esi
movl %esi, 0x54(%rbx)
movq $0x2, 0x58(%rbx)
jmp 0x71d0
movl %esi, %eax
andb $-0x8, %al
cmpb $-0x10, %al
jne 0x71d2
andl $0x7, %esi
movl %esi, 0x54(%rbx)
movq $0x3, 0x58(%rbx)
jmp 0x71d0
cmpl $0x0, 0x5c(%rbx)
jne 0x7150
cmpb $-0x79, %sil
jbe 0x7146
jmp 0x7150
cmpl $0x0, 0x5c(%rbx)
jne 0x7150
cmpb $-0x61, %sil
jbe 0x7146
jmp 0x7150
cmpl $0x0, 0x5c(%rbx)
jne 0x7150
cmpb $-0x71, %sil
jbe 0x7146
jmp 0x7150
cmpl $0x0, 0x5c(%rbx)
jne 0x7150
cmpb $-0x7d, %sil
ja 0x7150
cmpl $0x0, 0x54(%rbx)
jne 0x7150
movb $0x0, 0x60(%rbx)
movl 0x54(%rbx), %edx
movl 0x5c(%rbx), %edi
movl %edx, %ecx
shll $0x6, %ecx
andl $0x3f, %esi
orl %ecx, %esi
movl %esi, 0x54(%rbx)
incl %edi
movl %edi, 0x5c(%rbx)
cmpl %eax, %edi
jl 0x71d0
movb 0x60(%rbx), %al
xorb $0x1, %al
andl $0x3ffffe0, %edx        # imm = 0x3FFFFE0
cmpl $0x360, %edx            # imm = 0x360
sete %dl
orb %al, %dl
leal -0xfdd0(%rsi), %eax
cmpl $0x20, %eax
setb %al
orb %dl, %al
movl $0x3f, %eax
jne 0x71b3
movl %esi, %eax
notl %eax
testl $0xfffe, %eax           # imm = 0xFFFE
movl $0x3f, %eax
cmovel %eax, %esi
cmpl $0x110000, %ecx         # imm = 0x110000
cmovael %eax, %esi
movl %esi, %eax
movq %rbx, %rdi
movl %eax, %esi
callq 0x414e
movl $0x0, 0x5c(%rbx)
movq $0x0, 0x54(%rbx)
movb $0x1, 0x60(%rbx)
popq %rbx
retq
movl %esi, %eax
andb $-0x4, %al
cmpb $-0x8, %al
jne 0x71ea
andl $0x3, %esi
movl %esi, 0x54(%rbx)
movq $0x4, 0x58(%rbx)
jmp 0x71d0
movl %esi, %eax
andb $-0x2, %al
cmpb $-0x4, %al
jne 0x7202
andl $0x1, %esi
movl %esi, 0x54(%rbx)
movq $0x5, 0x58(%rbx)
jmp 0x71d0
movq %rbx, %rdi
movl $0x3f, %esi
jmp 0x71b8