// File: /workspace/github_c_makefile_star2_O0/mloar[P]charset/euc.c
// Function: read_euc
static void read_euc(charset_spec const *charset, long int input_chr,
		     charset_state *state,
		     void (*emit)(void *ctx, long int output), void *emitctx)
{
    struct euc const *euc = (struct euc *)charset->data;

    /*
     * For EUC input, our state variable divides into three parts:
     * 
     * 	- Topmost nibble (bits 31:28) is nonzero if we're
     * 	  accumulating a multibyte character, and it indicates
     * 	  which section we're in: 1 for GR chars, 2 for things
     * 	  beginning with SS2, 3 for things beginning with SS3.
     * 
     * 	- Next nibble (bits 27:24) indicates how many bytes of the
     * 	  character we've accumulated so far.
     * 
     * 	- The rest (bits 23:0) are those bytes in full, accumulated
     * 	  as a large integer (so that seeing A1 A2 A3, in a
     * 	  hypothetical EUC whose GR encoding is three-byte, runs
     * 	  our state variable from 0 -> 0x110000A1 -> 0x1200A1A2 ->
     * 	  0x13A1A2A3, at which point it gets translated and output
     * 	  and resets to zero).
     */

    if (state->s0 != 0) {

	/*
	 * At this point, no matter whether we had an SS2 or SS3
	 * introducer or not, we _always_ expect a GR character.
	 * Anything else causes us to emit ERROR for an incomplete
	 * character, and then reset to state 0 to process the
	 * character in its own way.
	 */
	if (input_chr < 0xA1 || input_chr == 0xFF) {
	    emit(emitctx, ERROR);
	    state->s0 = 0;
	} else
	    state->s0 = (((state->s0 & 0xFF000000) + 0x01000000) |
			 ((state->s0 & 0x0000FFFF) << 8) | input_chr);

    }

    if (state->s0 == 0) {
	/*
	 * The input character determines which of the four
	 * possible charsets we're going to be in.
	 */
	if (input_chr < 0x80) {	       /* this is always ASCII */
	    emit(emitctx, input_chr);
	} else if (input_chr == 0x8E) {/* SS2 means charset 2 */
	    state->s0 = 0x20000000;
	} else if (input_chr == 0x8F) {/* SS3 means charset 3 */
	    state->s0 = 0x30000000;
	} else if (input_chr < 0xA1 || input_chr == 0xFF) {   /* errors */
	    emit(emitctx, ERROR);
	} else {		       /* A1-FE means charset 1 */
	    state->s0 = 0x11000000 | input_chr;
	}
    }

    /*
     * Finally, if we have accumulated a complete character, output
     * it.
     */
    if (state->s0 != 0 &&
	((state->s0 & 0x0F000000) >> 24) >=
	(unsigned)euc->nchars[(state->s0 >> 28)-1]) {
	emit(emitctx, euc->to_ucs(state->s0));
	state->s0 = 0;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
je 0x6ccb
cmpq $0xa1, -0x10(%rbp)
jl 0x6c76
cmpq $0xff, -0x10(%rbp)
jne 0x6c92
movq -0x20(%rbp), %rax
movq -0x28(%rbp), %rdi
movl $0xffff, %esi           # imm = 0xFFFF
callq *%rax
movq -0x18(%rbp), %rax
movq $0x0, (%rax)
jmp 0x6cc9
movq -0x18(%rbp), %rax
movabsq $0xff000000, %rcx       # imm = 0xFF000000
andq (%rax), %rcx
addq $0x1000000, %rcx        # imm = 0x1000000
movq -0x18(%rbp), %rax
movq (%rax), %rax
andq $0xffff, %rax           # imm = 0xFFFF
shlq $0x8, %rax
orq %rax, %rcx
orq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x6ccb
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x6d60
cmpq $0x80, -0x10(%rbp)
jge 0x6cf3
movq -0x20(%rbp), %rax
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq *%rax
jmp 0x6d5e
cmpq $0x8e, -0x10(%rbp)
jne 0x6d0a
movq -0x18(%rbp), %rax
movq $0x20000000, (%rax)     # imm = 0x20000000
jmp 0x6d5c
cmpq $0x8f, -0x10(%rbp)
jne 0x6d21
movq -0x18(%rbp), %rax
movq $0x30000000, (%rax)     # imm = 0x30000000
jmp 0x6d5a
cmpq $0xa1, -0x10(%rbp)
jl 0x6d35
cmpq $0xff, -0x10(%rbp)
jne 0x6d46
movq -0x20(%rbp), %rax
movq -0x28(%rbp), %rdi
movl $0xffff, %esi           # imm = 0xFFFF
callq *%rax
jmp 0x6d58
movq -0x10(%rbp), %rcx
orq $0x11000000, %rcx       # imm = 0x11000000
movq -0x18(%rbp), %rax
movq %rcx, (%rax)
jmp 0x6d5a
jmp 0x6d5c
jmp 0x6d5e
jmp 0x6d60
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
je 0x6dcf
movq -0x18(%rbp), %rax
movq (%rax), %rax
andq $0xf000000, %rax        # imm = 0xF000000
shrq $0x18, %rax
movq -0x30(%rbp), %rcx
movq -0x18(%rbp), %rdx
movq (%rdx), %rdx
shrq $0x1c, %rdx
subq $0x1, %rdx
movl (%rcx,%rdx,4), %ecx
cmpq %rcx, %rax
jb 0x6dcf
movq -0x20(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x18(%rbp), %rcx
movq (%rcx), %rdi
callq *%rax
movq -0x40(%rbp), %rdi
movq %rax, %rsi
movq -0x38(%rbp), %rax
callq *%rax
movq -0x18(%rbp), %rax
movq $0x0, (%rax)
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)