// File: /workspace/github_c_makefile_star2_O0/mloar[P]charset/hz.c
// Function: read_hz
static void read_hz(charset_spec const *charset, long int input_chr,
		    charset_state *state,
		    void (*emit)(void *ctx, long int output), void *emitctx)
{
    /*
     * When reading, our state variables are:
     * 
     *  - s0 is 0 in ASCII mode, 1 in GB2312 mode.
     * 
     * 	- s1 stores a character we have just seen but not fully
     * 	  processed. So in ASCII mode, this can only ever be zero
     * 	  (no character) or 0x7E (~); in GB2312 mode it can be
     * 	  anything from 0x21-0x7E.
     */

    UNUSEDARG(charset);

    if (state->s0 == 0) {
	/*
	 * ASCII mode.
	 */

	if (state->s1) {
	    assert(state->s1 == '~');
	    state->s1 = 0;
	    /* Process the character after a tilde. */
	    switch (input_chr) {
	      case '~':
		emit(emitctx, input_chr);
		return;
	      case '\n':
		return;		       /* ~\n is ignored */
	      case '{':
		state->s0 = 1;	       /* switch to GB2312 mode */
		return;
	    }
	} else if (input_chr == '~') {
	    state->s1 = '~';
	    return;
	} else {
	    /* In ASCII mode, any non-tildes go straight  */
	    emit(emitctx, input_chr);
	    return;
	}
    } else {
	/*
	 * GB2312 mode. As I understand it, we expect never to see
	 * anything in this mode that isn't 0x21-0x7E. So if we do,
	 * we'll simply throw an error and return to ASCII mode.
	 */
	if (input_chr < 0x21 || input_chr > 0x7E) {
	    emit(emitctx, ERROR);
	    state->s0 = state->s1 = 0;
	    return;
	}

	/*
	 * So if we don't have a character stored already, store
	 * this one...
	 */
	if (!state->s1) {
	    state->s1 = input_chr;
	    return;
	}

	/*
	 * ... otherwise, combine the stored char with this one.
	 * This will give either `~}', the escape sequence to
	 * return to ASCII mode, or something which we translate
	 * through GB2312.
	 */
	if (state->s1 == '~' && input_chr == '}') {
	    state->s1 = state->s0 = 0;
	    return;
	}

	emit(emitctx, gb2312_to_unicode(state->s1 - 0x21, input_chr - 0x21));
	state->s1 = 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 %rax, -0x8(%rbp)
movq -0x18(%rbp), %rax
cmpq $0x0, (%rax)
jne 0x763b
movq -0x18(%rbp), %rax
cmpq $0x0, 0x8(%rax)
je 0x760b
movq -0x18(%rbp), %rax
cmpq $0x7e, 0x8(%rax)
jne 0x758e
jmp 0x75ad
leaq 0x57255(%rip), %rdi     # 0x5e7ea
leaq 0x5725f(%rip), %rsi     # 0x5e7fb
movl $0x23, %edx
leaq 0x57258(%rip), %rcx     # 0x5e800
callq 0x6050
movq -0x18(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x10(%rbp), %rax
movq %rax, -0x30(%rbp)
subq $0xa, %rax
je 0x75f4
jmp 0x75c9
movq -0x30(%rbp), %rax
subq $0x7b, %rax
je 0x75f9
jmp 0x75d5
movq -0x30(%rbp), %rax
subq $0x7e, %rax
jne 0x7609
jmp 0x75e1
movq -0x20(%rbp), %rax
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq *%rax
jmp 0x76fe
jmp 0x76fe
movq -0x18(%rbp), %rax
movq $0x1, (%rax)
jmp 0x76fe
jmp 0x7636
cmpq $0x7e, -0x10(%rbp)
jne 0x7623
movq -0x18(%rbp), %rax
movq $0x7e, 0x8(%rax)
jmp 0x76fe
movq -0x20(%rbp), %rax
movq -0x28(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq *%rax
jmp 0x76fe
jmp 0x76fe
cmpq $0x21, -0x10(%rbp)
jl 0x7649
cmpq $0x7e, -0x10(%rbp)
jle 0x7674
movq -0x20(%rbp), %rax
movq -0x28(%rbp), %rdi
movl $0xffff, %esi           # imm = 0xFFFF
callq *%rax
movq -0x18(%rbp), %rax
movq $0x0, 0x8(%rax)
movq -0x18(%rbp), %rax
movq $0x0, (%rax)
jmp 0x76fe
movq -0x18(%rbp), %rax
cmpq $0x0, 0x8(%rax)
jne 0x768d
movq -0x10(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
jmp 0x76fe
movq -0x18(%rbp), %rax
cmpq $0x7e, 0x8(%rax)
jne 0x76b8
cmpq $0x7d, -0x10(%rbp)
jne 0x76b8
movq -0x18(%rbp), %rax
movq $0x0, (%rax)
movq -0x18(%rbp), %rax
movq $0x0, 0x8(%rax)
jmp 0x76fe
movq -0x20(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x18(%rbp), %rax
movq 0x8(%rax), %rax
subq $0x21, %rax
movl %eax, %edi
movq -0x10(%rbp), %rax
subq $0x21, %rax
movl %eax, %esi
callq 0x73d0
movq -0x40(%rbp), %rdi
movq %rax, %rsi
movq -0x38(%rbp), %rax
callq *%rax
movq -0x18(%rbp), %rax
movq $0x0, 0x8(%rax)
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)