// File: /workspace/github_c_makefile_star2_O3/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 0x8ad6
leaq 0x14(%rsp), %rsi
leaq 0x20(%rsp), %rdx
movq %r12, %rdi
callq *0x40(%r13)
testl %eax, %eax
je 0x8d3a
movq %r15, 0x8(%rsp)
testb $-0x80, 0xb(%r15)
jne 0x8b1d
movq 0x20(%r13), %rax
movq 0x8(%rsp), %rcx
movq %rax, 0x8(%rcx)
movq 0x28(%r13), %rax
testq %rax, %rax
je 0x8b1d
movb (%rax), %al
testb %al, %al
je 0x8b1d
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 0x8b04
cmpq $-0x1, %r12
je 0x8c16
movslq 0x8(%r13), %rcx
testq %rcx, %rcx
movq 0x8(%rsp), %r15
jle 0x8b59
movq (%r13), %rax
movl 0x14(%rsp), %esi
shlq $0x5, %rcx
xorl %ebp, %ebp
cmpl %esi, 0x1c(%rax,%rbp)
jne 0x8b50
testb $-0x80, 0x18(%rax,%rbp)
je 0x8b78
addq $0x20, %rbp
cmpq %rbp, %rcx
jne 0x8b43
leaq 0x54201(%rip), %rdi     # 0x5cd61
leaq 0x5418f(%rip), %rsi     # 0x5ccf6
leaq 0x54205(%rip), %rcx     # 0x5cd73
movl $0x187, %edx            # imm = 0x187
callq 0x6060
movl 0x18(%rax,%rbp), %r8d
movq 0x8(%r15), %rdx
leal (%r8,%r8), %ecx
leal (%rcx,%rcx,2), %ecx
movq %rdx, %rdi
shrq %cl, %rdi
movl %r8d, %r12d
andl $0xffffff7f, %r12d      # imm = 0xFFFFFF7F
andl $0x3f, %edi
cmpl %esi, %edi
je 0x8bed
movq (%rax,%rbp), %rcx
movb (%rcx), %cl
testb %cl, %cl
je 0x8bdf
movq %r8, 0x18(%rsp)
movl $0x1, %r15d
movsbq %cl, %rsi
movq %rbx, %rdi
callq *%r14
movq (%r13), %rax
movq (%rax,%rbp), %rcx
movb (%rcx,%r15), %cl
incq %r15
testb %cl, %cl
jne 0x8bb4
movq 0x8(%rsp), %r15
movq 0x8(%r15), %rdx
movq 0x18(%rsp), %r8
andq 0x8(%rax,%rbp), %rdx
xorq 0x10(%rax,%rbp), %rdx
movq %rdx, 0x8(%r15)
cmpl $0x2, %r12d
jl 0x8c9e
movl $0x1b, %esi
movq %rbx, %rdi
callq *%r14
addq $0x4c, %r12
movq %rbx, %rdi
movq %r12, %rsi
callq *%r14
xorl %ebp, %ebp
jmp 0x8cf7
movq 0x18(%r13), %rcx
movb (%rcx), %dl
testb %dl, %dl
je 0x8c93
movq (%r13), %rax
xorl %r12d, %r12d
movq 0x8(%rsp), %rdi
movsbq %dl, %rbp
decq %rbp
movq 0x8(%rdi), %rdx
shlq $0x5, %rbp
movq 0x8(%rax,%rbp), %rsi
andq %rdx, %rsi
xorq 0x10(%rax,%rbp), %rsi
movq %rsi, 0x8(%rdi)
cmpq %rdx, %rsi
je 0x8c87
movq (%rax,%rbp), %rdx
movb (%rdx), %dl
testb %dl, %dl
je 0x8c87
movl $0x1, %r15d
movsbq %dl, %rsi
movq %rbx, %rdi
callq *%r14
movq (%r13), %rax
movq (%rax,%rbp), %rcx
movb (%rcx,%r15), %dl
incq %r15
testb %dl, %dl
jne 0x8c61
movq 0x18(%r13), %rcx
movq 0x8(%rsp), %rdi
movb 0x1(%rcx,%r12), %dl
incq %r12
testb %dl, %dl
jne 0x8c2c
movl $0x1, %r13d
jmp 0x8d3d
cmpl $0x1, %r12d
jne 0x8cb9
cmpl $0x0, 0x30(%r13)
je 0x8cb9
movl %edx, %eax
movl $0x80, %ebp
andl $0x70000000, %eax       # imm = 0x70000000
je 0x8cf7
shrl $0x1c, %edx
andl $0x7, %edx
cmpl %r12d, %edx
je 0x8c0f
xorl %ebp, %ebp
cmpl $0x1, %r12d
movl $0x0, %esi
adcq $0xe, %rsi
movq %rbx, %rdi
movq %r8, %r12
callq *%r14
movq 0x8(%r15), %rax
andl $0x8fffffff, %eax       # imm = 0x8FFFFFFF
shll $0x1c, %r12d
movslq %r12d, %rcx
orq %rax, %rcx
movq %rcx, 0x8(%r15)
movq 0x10(%r13), %rax
movslq 0x14(%rsp), %rcx
movsbl (%rax,%rcx), %r12d
movl $0x1, %r13d
testl %r12d, %r12d
je 0x8d3d
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 0x8d18
jmp 0x8d3d
xorl %r13d, %r13d
movl %r13d, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq