// File: /workspace/github_c_makefile_star2_O2/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, 0x8(%rsp)
movq %rsi, %r12
movq 0x18(%rdi), %r13
testq %rsi, %rsi
js 0x8968
leaq 0x14(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movq %r12, %rdi
callq *0x40(%r13)
testl %eax, %eax
je 0x8b70
movq 0x8(%rsp), %rax
testb $-0x80, 0xb(%rax)
jne 0x89a4
movq 0x20(%r13), %rax
movq 0x8(%rsp), %rcx
movq %rax, 0x8(%rcx)
movq 0x28(%r13), %rax
testq %rax, %rax
je 0x89a4
xorl %ebp, %ebp
movsbq (%rax,%rbp), %rsi
testq %rsi, %rsi
je 0x89a4
movq %rbx, %rdi
callq *%r14
incq %rbp
movq 0x28(%r13), %rax
jmp 0x898b
cmpq $-0x1, %r12
je 0x8a33
movl 0x8(%r13), %ecx
movl 0x14(%rsp), %edx
xorl %ebp, %ebp
testl %ecx, %ecx
cmovlel %ebp, %ecx
shlq $0x5, %rcx
cmpq %rbp, %rcx
je 0x8b85
movq (%r13), %rax
cmpl %edx, 0x1c(%rax,%rbp)
jne 0x89db
testb $-0x80, 0x18(%rax,%rbp)
je 0x89e1
addq $0x20, %rbp
jmp 0x89c1
movl 0x18(%rax,%rbp), %r15d
movq 0x8(%rsp), %rcx
movq 0x8(%rcx), %rsi
imull $0x6, %r15d, %ecx
movq %rsi, %rdi
shrq %cl, %rdi
movl %r15d, %r12d
andl $0xffffff7f, %r12d      # imm = 0xFFFFFF7F
andl $0x3f, %edi
cmpl %edx, %edi
je 0x8ab7
movq %r12, 0x18(%rsp)
xorl %r12d, %r12d
movq (%rax,%rbp), %rcx
movsbq (%rcx,%r12), %rsi
testq %rsi, %rsi
je 0x8a9b
movq %rbx, %rdi
callq *%r14
incq %r12
movq (%r13), %rax
jmp 0x8a16
xorl %ebp, %ebp
movq 0x18(%r13), %rax
movsbq (%rax,%rbp), %r12
testq %r12, %r12
je 0x8a92
decq %r12
movq 0x8(%rsp), %rsi
movq 0x8(%rsi), %rcx
movq (%r13), %rax
shlq $0x5, %r12
movq 0x8(%rax,%r12), %rdx
andq %rcx, %rdx
xorq 0x10(%rax,%r12), %rdx
movq %rdx, 0x8(%rsi)
cmpq %rcx, %rdx
jne 0x8a72
incq %rbp
jmp 0x8a35
xorl %r15d, %r15d
movq (%rax,%r12), %rax
movsbq (%rax,%r15), %rsi
testq %rsi, %rsi
je 0x8a6d
movq %rbx, %rdi
callq *%r14
incq %r15
movq (%r13), %rax
jmp 0x8a75
pushq $0x1
popq %r12
jmp 0x8b73
movq 0x8(%rsp), %rcx
movq 0x8(%rcx), %rsi
andq 0x8(%rax,%rbp), %rsi
xorq 0x10(%rax,%rbp), %rsi
movq %rsi, 0x8(%rcx)
movq 0x18(%rsp), %r12
cmpl $0x2, %r12d
jl 0x8ad7
pushq $0x1b
popq %rsi
movq %rbx, %rdi
callq *%r14
addq $0x4c, %r12
movq %rbx, %rdi
movq %r12, %rsi
callq *%r14
xorl %ebp, %ebp
jmp 0x8b2e
cmpl $0x1, %r12d
jne 0x8af2
cmpl $0x0, 0x30(%r13)
je 0x8af2
movl %esi, %eax
movl $0x80, %ebp
andl $0x70000000, %eax       # imm = 0x70000000
je 0x8b2e
shrl $0x1c, %esi
andl $0x7, %esi
cmpl %r12d, %esi
je 0x8ad3
xorl %ebp, %ebp
cmpl $0x1, %r12d
movl $0x0, %esi
adcq $0xe, %rsi
movq %rbx, %rdi
callq *%r14
movq 0x8(%rsp), %rdx
movq 0x8(%rdx), %rax
andl $0x8fffffff, %eax       # imm = 0x8FFFFFFF
shll $0x1c, %r15d
movslq %r15d, %rcx
orq %rax, %rcx
movq %rcx, 0x8(%rdx)
movq 0x10(%r13), %rax
movslq 0x14(%rsp), %rcx
movsbq (%rax,%rcx), %rax
movl %eax, %eax
leaq -0x8(,%rax,8), %r15
pushq $0x1
popq %r12
cmpq $-0x8, %r15
je 0x8b73
movq 0x20(%rsp), %rax
movl %r15d, %ecx
andb $-0x8, %cl
shrq %cl, %rax
movzbl %al, %esi
orq %rbp, %rsi
movq %rbx, %rdi
callq *%r14
addq $-0x8, %r15
jmp 0x8b4a
xorl %r12d, %r12d
movl %r12d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x531d5(%rip), %rdi     # 0x5bd61
leaq 0x53163(%rip), %rsi     # 0x5bcf6
leaq 0x531d9(%rip), %rcx     # 0x5bd73
movl $0x187, %edx            # imm = 0x187
callq 0x6060