// File: /workspace/github_c_makefile_star2_O1/mloar[P]charset/iso2022s.c
// Function: write_iso2022s
static int write_iso2022s(charset_spec const *charset, long int input_chr,
			  charset_state *state,
			  void (*emit)(void *ctx, long int output),
			  void *emitctx)
{
    struct iso2022 const *iso = (struct iso2022 *)charset->data;
    int subcharset, len, i, j, cont, topbit = 0;
    unsigned long bytes;

    /*
     * For output, our s1 state variable contains most of the same
     * stuff as it did for input - initial-state indicator bit,
     * current container, and current subcharset selected in each
     * container.
     */

    /*
     * Analyse the character and find out what subcharset it needs
     * to go in.
     */
    if (input_chr >= 0 && !iso->from_ucs(input_chr, &subcharset, &bytes))
	return FALSE;

    if (!(state->s1 & 0x80000000)) {
	state->s1 = iso->s1;
	if (iso->initial_sequence)
	    for (i = 0; iso->initial_sequence[i]; i++)
		emit(emitctx, iso->initial_sequence[i]);
    }

    if (input_chr == -1) {
	unsigned long oldstate;
	int k;

	/*
	 * Special case: reset encoding state.
	 */
	for (i = 0; iso->reset[i]; i++) {
	    j = iso->reset[i] - 1;
	    oldstate = state->s1;
	    state->s1 &= iso->escapes[j].andbits;
	    state->s1 ^= iso->escapes[j].xorbits;
	    if (state->s1 != oldstate) {
		/* We must actually emit this sequence. */
		for (k = 0; iso->escapes[j].sequence[k]; k++)
		    emit(emitctx, iso->escapes[j].sequence[k]);
	    }
	}

	return TRUE;
    }

    /*
     * Now begins the fun. We now know what subcharset we want. So
     * we must find out which container we should select it into,
     * select it into it if necessary, select that _container_ if
     * necessary, and then output the given bytes.
     */
    for (i = 0; i < iso->nescapes; i++)
	if (iso->escapes[i].subcharset == subcharset &&
	    !(iso->escapes[i].container & RO))
	    break;
    assert(i < iso->nescapes);

    /*
     * We've found the escape sequence which would select this
     * subcharset into a container. However, that subcharset might
     * already _be_ selected in that container! Check before we go
     * to the effort of emitting the sequence.
     */
    cont = iso->escapes[i].container &~ RO;
    if (((state->s1 >> (6*cont)) & 0x3F) != (unsigned)subcharset) {
	for (j = 0; iso->escapes[i].sequence[j]; j++)
	    emit(emitctx, iso->escapes[i].sequence[j]);
	state->s1 &= iso->escapes[i].andbits;
	state->s1 ^= iso->escapes[i].xorbits;
    }

    /*
     * Now we know what container our subcharset is in, so we want
     * to select that container.
     */
    if (cont > 1) {
	/* SS2 or SS3; just output the sequence and be done. */
	emit(emitctx, ESC);
	emit(emitctx, 'L' + cont);     /* comes out to 'N' or 'O' */
    } else {
	/*
	 * Emit SI or SO, but only if the current container isn't already
	 * the right one.
	 * 
	 * Also, in an 8-bit subset, we need not do this; we'll
	 * just use 8-bit characters to output SO-container
	 * characters.
	 */
	if (iso->eightbit && cont == 1 && ((state->s1 >> 28) & 7) == 0) {
	    topbit = 0x80;
	} else if (((state->s1 >> 28) & 7) != (unsigned)cont) {
	    emit(emitctx, cont ? SO : SI);
	    state->s1 = (state->s1 & 0x8FFFFFFF) | (cont << 28);
	}
    }

    /*
     * We're done. Subcharset is selected in container, container
     * is selected. All we need now is to write out the bytes.
     */
    len = iso->nbytes[subcharset];
    while (len--)
	emit(emitctx, ((bytes >> (8*len)) & 0xFF) | topbit);

    return TRUE;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r8, %rbx
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %r12
movq 0x18(%rdi), %r13
testq %rsi, %rsi
js 0x8c39
leaq 0x4(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movq %r12, %rdi
callq *0x40(%r13)
testl %eax, %eax
je 0x8e5d
movq %r15, 0x8(%rsp)
testb $-0x80, 0xb(%r15)
jne 0x8c82
movq 0x20(%r13), %rax
movq 0x8(%rsp), %rcx
movq %rax, 0x8(%rcx)
cmpq $0x0, 0x28(%r13)
je 0x8c82
movq 0x28(%r13), %rax
movb (%rax), %al
testb %al, %al
je 0x8c82
movl $0x1, %r15d
movsbq %al, %rsi
movq %rbx, %rdi
callq *%r14
movq 0x28(%r13), %rax
movb (%rax,%r15), %al
incq %r15
testb %al, %al
jne 0x8c69
cmpq $-0x1, %r12
je 0x8daf
movslq 0x8(%r13), %rax
testq %rax, %rax
setg %cl
movq 0x8(%rsp), %r15
jle 0x8cdc
movq (%r13), %rdx
movl 0x4(%rsp), %esi
movq %rax, %rdi
negq %rdi
movl $0x1c, %ebp
movl $0x1, %r8d
cmpl %esi, (%rdx,%rbp)
jne 0x8cc2
testb $-0x80, -0x4(%rdx,%rbp)
je 0x8cfb
cmpq %rax, %r8
setb %cl
addq $0x20, %rbp
leaq (%rdi,%r8), %r9
incq %r9
incq %r8
cmpq $0x1, %r9
jne 0x8cb6
leaq 0x5409a(%rip), %rdi     # 0x5cd7d
leaq 0x54028(%rip), %rsi     # 0x5cd12
leaq 0x5409e(%rip), %rcx     # 0x5cd8f
movl $0x187, %edx            # imm = 0x187
callq 0x6060
testb $0x1, %cl
je 0x8cdc
movq (%r13), %rax
movl -0x4(%rax,%rbp), %r12d
movl %r12d, %edx
movq 0x8(%r15), %rax
leal (%r12,%r12), %ecx
leal (%rcx,%rcx,2), %ecx
shrq %cl, %rax
andl $0xffffff7f, %edx       # imm = 0xFFFFFF7F
andl $0x3f, %eax
cmpl 0x4(%rsp), %eax
je 0x8d86
movq %rdx, 0x10(%rsp)
movq %r12, 0x18(%rsp)
movq (%r13), %rax
movq -0x1c(%rax,%rbp), %rcx
movb (%rcx), %cl
testb %cl, %cl
je 0x8d66
movl $0x1, %r12d
movsbq %cl, %rsi
movq %rbx, %rdi
callq *%r14
movq (%r13), %rax
movq -0x1c(%rax,%rbp), %rcx
movb (%rcx,%r12), %cl
incq %r12
testb %cl, %cl
jne 0x8d48
movq 0x8(%r15), %rcx
andq -0x14(%rax,%rbp), %rcx
movq %rcx, 0x8(%r15)
xorq -0xc(%rax,%rbp), %rcx
movq %rcx, 0x8(%r15)
movq 0x18(%rsp), %r12
movq 0x10(%rsp), %rdx
cmpl $0x2, %edx
jl 0x8e38
movq %rdx, %r15
movl $0x1b, %esi
movq %rbx, %rdi
callq *%r14
addq $0x4c, %r15
movq %rbx, %rdi
movq %r15, %rsi
callq *%r14
jmp 0x8e59
movq 0x18(%r13), %rax
movb (%rax), %al
testb %al, %al
je 0x8e2d
xorl %ebp, %ebp
movsbq %al, %r12
decq %r12
movq 0x8(%rsp), %rsi
movq 0x8(%rsi), %rax
movq (%r13), %rcx
shlq $0x5, %r12
movq 0x8(%rcx,%r12), %rdx
andq %rax, %rdx
movq %rdx, 0x8(%rsi)
xorq 0x10(%rcx,%r12), %rdx
movq %rdx, 0x8(%rsi)
cmpq %rax, %rdx
je 0x8e1e
movq (%r13), %rax
movq (%rax,%r12), %rax
movb (%rax), %al
testb %al, %al
je 0x8e1e
movl $0x1, %r15d
movsbq %al, %rsi
movq %rbx, %rdi
callq *%r14
movq (%r13), %rax
movq (%rax,%r12), %rax
movb (%rax,%r15), %al
incq %r15
testb %al, %al
jne 0x8e01
movq 0x18(%r13), %rax
movb 0x1(%rax,%rbp), %al
incq %rbp
testb %al, %al
jne 0x8dbb
movl $0x1, %r13d
jmp 0x8ed5
cmpl $0x1, %edx
jne 0x8e4b
cmpl $0x0, 0x30(%r13)
je 0x8e4b
testb $0x70, 0xb(%r15)
je 0x8e8f
movl 0x8(%r15), %eax
shrl $0x1c, %eax
andl $0x7, %eax
cmpl %edx, %eax
jne 0x8e62
xorl %ebp, %ebp
jmp 0x8e94
xorl %r13d, %r13d
jmp 0x8ed5
xorl %ebp, %ebp
cmpl $0x1, %edx
movl $0x0, %esi
adcq $0xe, %rsi
movq %rbx, %rdi
callq *%r14
movq 0x8(%r15), %rax
andl $0x8fffffff, %eax       # imm = 0x8FFFFFFF
shll $0x1c, %r12d
movslq %r12d, %rcx
orq %rax, %rcx
movq %rcx, 0x8(%r15)
jmp 0x8e94
movl $0x80, %ebp
movq 0x10(%r13), %rax
movslq 0x4(%rsp), %rcx
movsbl (%rax,%rcx), %r12d
movl $0x1, %r13d
testl %r12d, %r12d
je 0x8ed5
leal -0x8(,%r12,8), %r15d
movq 0x20(%rsp), %rax
movl %r15d, %ecx
shrq %cl, %rax
movzbl %al, %esi
orq %rbp, %rsi
movq %rbx, %rdi
callq *%r14
addl $-0x8, %r15d
decl %r12d
jne 0x8eb5
movl %r13d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq