// File: /workspace/github_c_makefile_star2_O1/mloar[P]charset/iso2022.c
// Function: docs_char
static void docs_char(charset_state *state,
		      void (*emit)(void *ctx, long int output),
		      void *emitctx, int cset, char *data, int datalen)
{
    int curr_cset, currlen, i;

    /*
     * cset is the index into ctext_encodings[]. It can also be -1
     * to mean DOCS UTF-8, or -2 to mean no DOCS (ordinary 2022).
     * In the latter case, `chr' is ignored.
     */

    /*
     * First, terminate a DOCS segment if necessary. We always have
     * to terminate a DOCS segment if one is active and we're about
     * to switch to a different one; we might also have to
     * terminate a length-encoded DOCS segment if we've run out of
     * storage space to accumulate characters in it.
     */
    curr_cset = ((state->s1 >> 14) & 7) - 2;
    currlen = ((state->s1 >> 11) & 7);
    if ((curr_cset != -2 && curr_cset != cset) ||
	(curr_cset >= 0 && currlen + datalen > 5)) {
	if (curr_cset == -1) {
	    /*
	     * Terminating DOCS UTF-8 is easy.
	     */
	    emit(emitctx, ESC);
	    emit(emitctx, '%');
	    emit(emitctx, '@');
	} else {
	    int len;

	    /*
	     * To terminate a length-encoded DOCS segment we must
	     * actually output the whole thing.
	     */
	    emit(emitctx, ESC);
	    emit(emitctx, '%');
	    emit(emitctx, '/');
	    emit(emitctx, '0' + ctext_encodings[curr_cset].octets_per_char);
	    len = currlen + datalen +
		strlen(ctext_encodings[curr_cset].name);
	    assert(len < (1 << 14));
	    emit(emitctx, 0x80 | ((len >> 7) & 0x7F));
	    emit(emitctx, 0x80 | ((len     ) & 0x7F));
	    /* The name stored in ctext_encodings[] includes the trailing \2 */
	    for (i = 0; ctext_encodings[curr_cset].name[i]; i++)
		emit(emitctx, ctext_encodings[curr_cset].name[i]);
	    for (i = 0; i < currlen; i++)
		emit(emitctx,
		     (i == 0 ? state->s1 : state->s0 >> (8*(4-i))) & 0xFF);
	    for (i = 0; i < datalen; i++)
		emit(emitctx, data[i]);

	    /*
	     * We've now dealt with the input data, so clear it so
	     * we don't try to do so again below.
	     */
	    datalen = 0;
	}
	curr_cset = -2;
    }

    /*
     * Now, start a DOCS segment if necessary.
     */
    if (curr_cset != cset) {
	assert(cset != -2);
	if (cset == -1) {
	    /*
	     * Start DOCS UTF-8.
	     */
	    emit(emitctx, ESC);
	    emit(emitctx, '%');
	    emit(emitctx, 'G');
	} else {
	    /*
	     * Starting a length-encoded DOCS segment is simply a
	     * matter of setting our stored length counter to zero.
	     */
	    currlen = 0;
	    state->s1 &= ~(7 << 11);
	    state->s1 &= ~0xFF;
	    state->s0 = 0;
	}
    }
    state->s1 &= ~(7 << 14);
    assert((cset+2) >= 0 && (cset+2) < 8);
    state->s1 |= ((cset+2) << 14);

    /*
     * Now we're in the right DOCS state. Actually deal with the
     * input data, if we haven't already done so above.
     */
    if (datalen > 0) {
	assert(cset != 2);
	if (cset == -1) {
	    /*
	     * In DOCS UTF-8, we output data as soon as we get it.
	     */
	    for (i = 0; i < datalen; i++)
		emit(emitctx, data[i]);
	} else {
	    /*
	     * In length-encoded DOCS, we just store our data and
	     * bide our time. It'll all be output when we fill up
	     * or switch to another character set.
	     */
	    assert(currlen + datalen <= 5);   /* overflow handled already */
	    for (i = 0; i < datalen; i++) {
		if (currlen + i == 0)
		    state->s1 |= data[i] & 0xFF;
		else
		    state->s0 |= (data[i] & 0xFF) << (8*(4-(currlen+i)));
	    }
	    currlen += datalen;
	    assert(currlen >= 0 && currlen < 8);
	    state->s1 &= ~(7 << 11);
	    state->s1 |= (currlen << 11);
	}
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movl %r9d, %r13d
movq %r8, %rbx
movq %rdx, %r15
movq %rsi, %r12
movq %rdi, %r14
movl 0x8(%rdi), %ebp
movl %ebp, %eax
shrl $0xe, %eax
andl $0x7, %eax
leal -0x2(%rax), %edi
shrl $0xb, %ebp
andl $0x7, %ebp
testl %eax, %eax
sete %sil
cmpl %ecx, %edi
sete %dl
orb %sil, %dl
cmpb $0x1, %dl
movq %rcx, 0x10(%rsp)
jne 0x8489
cmpl $0x2, %eax
setae %al
leal (%rbp,%r13), %edx
cmpl $0x6, %edx
setge %dl
andb %al, %dl
cmpb $0x1, %dl
jne 0x8610
movq %r13, 0x18(%rsp)
movl $0x1b, %esi
movl %edi, %r13d
movq %r15, %rdi
callq *%r12
movl $0x25, %esi
movq %r15, %rdi
callq *%r12
cmpl $-0x1, %r13d
je 0x85e7
movl $0x2f, %esi
movq %r15, %rdi
callq *%r12
movslq %r13d, %rax
leaq (%rax,%rax,2), %r13
leaq 0x9f3f6(%rip), %rax     # 0xa78c0
movsbq 0x8(%rax,%r13,8), %rsi
addq $0x30, %rsi
movq %r15, %rdi
callq *%r12
movq %rbp, 0x8(%rsp)
movq 0x18(%rsp), %rax
addl %ebp, %eax
movl %eax, 0x24(%rsp)
leaq 0x9f3cf(%rip), %rax     # 0xa78c0
movq (%rax,%r13,8), %r13
movq %r13, %rdi
callq 0x6040
movq %rax, %rbp
addl 0x24(%rsp), %ebp
cmpl $0x4000, %ebp           # imm = 0x4000
jge 0x8749
movl %ebp, %esi
shrl $0x7, %esi
movl $0x80, %eax
orl %eax, %esi
movl $0xff, %eax
andl %eax, %esi
movq %r15, %rdi
callq *%r12
movl $0x80, %eax
orl %eax, %ebp
movl $0xff, %eax
andl %eax, %ebp
movq %r15, %rdi
movq %rbp, %rsi
callq *%r12
movb (%r13), %al
testb %al, %al
je 0x8560
incq %r13
movsbq %al, %rsi
movq %r15, %rdi
callq *%r12
movb (%r13), %al
incq %r13
testb %al, %al
jne 0x854b
cmpl $0x0, 0x8(%rsp)
je 0x85ad
movq 0x8(%rsp), %rax
leal (,%rax,8), %ebp
movl $0x20, %r13d
cmpq $0x20, %r13
jne 0x8586
movzbl 0x8(%r14), %eax
jmp 0x858f
movq (%r14), %rax
movl %r13d, %ecx
shrq %cl, %rax
movzbl %al, %esi
movq %r15, %rdi
callq *%r12
leaq -0x8(,%r13), %rax
addq %rbp, %rax
addq $-0x8, %r13
cmpq $0x20, %rax
jne 0x8579
movl $0xfffffffe, %edi       # imm = 0xFFFFFFFE
movq 0x18(%rsp), %rax
testl %eax, %eax
jle 0x8603
movl %eax, %r13d
xorl %ebp, %ebp
movsbq (%rbx,%rbp), %rsi
movq %r15, %rdi
callq *%r12
incq %rbp
cmpq %rbp, %r13
jne 0x85c0
xorl %r13d, %r13d
movq 0x8(%rsp), %rbp
movq 0x10(%rsp), %rcx
movl $0xfffffffe, %edi       # imm = 0xFFFFFFFE
jmp 0x8610
movl $0x40, %esi
movq %r15, %rdi
callq *%r12
movl $0xfffffffe, %edi       # imm = 0xFFFFFFFE
movq 0x10(%rsp), %rcx
movq 0x18(%rsp), %r13
jmp 0x8610
xorl %r13d, %r13d
movq 0x8(%rsp), %rbp
movq 0x10(%rsp), %rcx
cmpl %ecx, %edi
je 0x865a
cmpl $-0x1, %ecx
je 0x8634
cmpl $-0x2, %ecx
je 0x87a6
andw $0xc700, 0x8(%r14)      # imm = 0xC700
movq $0x0, (%r14)
xorl %ebp, %ebp
jmp 0x865a
movl $0x1b, %esi
movq %r15, %rdi
callq *%r12
movl $0x25, %esi
movq %r15, %rdi
callq *%r12
movl $0x47, %esi
movq %r15, %rdi
callq *%r12
movq 0x10(%rsp), %rcx
movq $-0x1c001, %rax         # imm = 0xFFFE3FFF
andq 0x8(%r14), %rax
movq %rax, 0x8(%r14)
leal 0x2(%rcx), %edx
cmpl $0x8, %edx
jae 0x872a
movl %ecx, %edx
shll $0xe, %edx
addl $0x8000, %edx           # imm = 0x8000
orq %rdx, %rax
movq %rax, 0x8(%r14)
testl %r13d, %r13d
jle 0x871b
cmpl $-0x1, %ecx
je 0x8702
cmpl $0x2, %ecx
je 0x8768
leal (%rbp,%r13), %eax
cmpl $0x5, %eax
jg 0x8787
movl %ebp, %edx
movl %r13d, %esi
shll $0x3, %ebp
movl $0x20, %ecx
subl %ebp, %ecx
negq %rdx
xorl %edi, %edi
movzbl (%rbx,%rdi), %r8d
movl %r8d, %r9d
shll %cl, %r9d
xorl %r10d, %r10d
cmpq %rdi, %rdx
movslq %r9d, %r9
cmoveq %r8, %r9
sete %r10b
orq %r9, (%r14,%r10,8)
incq %rdi
addl $-0x8, %ecx
cmpq %rdi, %rsi
jne 0x86c0
movq $-0x3801, %rcx          # imm = 0xC7FF
andq 0x8(%r14), %rcx
shll $0xb, %eax
orq %rcx, %rax
movq %rax, 0x8(%r14)
jmp 0x871b
movl %r13d, %r14d
xorl %r13d, %r13d
movsbq (%rbx,%r13), %rsi
movq %r15, %rdi
callq *%r12
incq %r13
cmpq %r13, %r14
jne 0x8708
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x54592(%rip), %rdi     # 0x5ccc3
leaq 0x542d1(%rip), %rsi     # 0x5ca09
leaq 0x54527(%rip), %rcx     # 0x5cc66
movl $0x39f, %edx            # imm = 0x39F
callq 0x6060
leaq 0x54506(%rip), %rdi     # 0x5cc56
leaq 0x542b2(%rip), %rsi     # 0x5ca09
leaq 0x54508(%rip), %rcx     # 0x5cc66
movl $0x372, %edx            # imm = 0x372
callq 0x6060
leaq 0x54572(%rip), %rdi     # 0x5cce1
leaq 0x54293(%rip), %rsi     # 0x5ca09
leaq 0x544e9(%rip), %rcx     # 0x5cc66
movl $0x3a7, %edx            # imm = 0x3A7
callq 0x6060
leaq 0x5455d(%rip), %rdi     # 0x5cceb
leaq 0x54274(%rip), %rsi     # 0x5ca09
leaq 0x544ca(%rip), %rcx     # 0x5cc66
movl $0x3b4, %edx            # imm = 0x3B4
callq 0x6060
leaq 0x5450b(%rip), %rdi     # 0x5ccb8
leaq 0x54255(%rip), %rsi     # 0x5ca09
leaq 0x544ab(%rip), %rcx     # 0x5cc66
movl $0x38b, %edx            # imm = 0x38B
callq 0x6060