// File: /workspace/github_c_makefile_star2_O0/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
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq %r8, -0x28(%rbp)
movl %r9d, -0x2c(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0xe, %rax
andq $0x7, %rax
subq $0x2, %rax
movl %eax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
shrq $0xb, %rax
andq $0x7, %rax
movl %eax, -0x34(%rbp)
cmpl $-0x2, -0x30(%rbp)
je 0x9707
movl -0x30(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jne 0x9720
cmpl $0x0, -0x30(%rbp)
jl 0x9943
movl -0x34(%rbp), %eax
addl -0x2c(%rbp), %eax
cmpl $0x5, %eax
jle 0x9943
cmpl $-0x1, -0x30(%rbp)
jne 0x9758
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movl $0x1b, %esi
callq *%rax
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movl $0x25, %esi
callq *%rax
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movl $0x40, %esi
callq *%rax
jmp 0x993c
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movl $0x1b, %esi
callq *%rax
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movl $0x25, %esi
callq *%rax
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movl $0x2f, %esi
callq *%rax
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movslq -0x30(%rbp), %rdx
leaq 0xa0128(%rip), %rcx     # 0xa98c0
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movsbl 0x8(%rcx), %ecx
addl $0x30, %ecx
movslq %ecx, %rsi
callq *%rax
movl -0x34(%rbp), %eax
addl -0x2c(%rbp), %eax
cltq
movq %rax, -0x48(%rbp)
movslq -0x30(%rbp), %rcx
leaq 0xa00fe(%rip), %rax     # 0xa98c0
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rdi
callq 0x6030
movq %rax, %rcx
movq -0x48(%rbp), %rax
addq %rcx, %rax
movl %eax, -0x3c(%rbp)
cmpl $0x4000, -0x3c(%rbp)    # imm = 0x4000
jge 0x97e9
jmp 0x9808
leaq 0x5545e(%rip), %rdi     # 0x5ec4e
leaq 0x5520a(%rip), %rsi     # 0x5ea01
movl $0x372, %edx            # imm = 0x372
leaq 0x5545b(%rip), %rcx     # 0x5ec5e
callq 0x6050
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movl -0x3c(%rbp), %ecx
sarl $0x7, %ecx
andl $0x7f, %ecx
orl $0x80, %ecx
movslq %ecx, %rsi
callq *%rax
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movl -0x3c(%rbp), %ecx
andl $0x7f, %ecx
orl $0x80, %ecx
movslq %ecx, %rsi
callq *%rax
movl $0x0, -0x38(%rbp)
movslq -0x30(%rbp), %rcx
leaq 0xa0071(%rip), %rax     # 0xa98c0
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rax
movslq -0x38(%rbp), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x9896
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movslq -0x30(%rbp), %rdx
leaq 0xa004a(%rip), %rcx     # 0xa98c0
imulq $0x18, %rdx, %rdx
addq %rdx, %rcx
movq (%rcx), %rcx
movslq -0x38(%rbp), %rdx
movsbq (%rcx,%rdx), %rsi
callq *%rax
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x9844
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x9904
movq -0x10(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpl $0x0, -0x38(%rbp)
jne 0x98c9
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x60(%rbp)
jmp 0x98e4
movq -0x8(%rbp), %rax
movq (%rax), %rax
movl $0x4, %ecx
subl -0x38(%rbp), %ecx
shll $0x3, %ecx
movl %ecx, %ecx
shrq %cl, %rax
movq %rax, -0x60(%rbp)
movq -0x58(%rbp), %rax
movq -0x50(%rbp), %rdi
movq -0x60(%rbp), %rsi
andq $0xff, %rsi
callq *%rax
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x989d
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x9935
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rcx
movslq -0x38(%rbp), %rdx
movsbq (%rcx,%rdx), %rsi
callq *%rax
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x990b
movl $0x0, -0x2c(%rbp)
movl $0xfffffffe, -0x30(%rbp) # imm = 0xFFFFFFFE
movl -0x30(%rbp), %eax
cmpl -0x1c(%rbp), %eax
je 0x99e5
cmpl $-0x2, -0x1c(%rbp)
je 0x9957
jmp 0x9976
leaq 0x55352(%rip), %rdi     # 0x5ecb0
leaq 0x5509c(%rip), %rsi     # 0x5ea01
movl $0x38b, %edx            # imm = 0x38B
leaq 0x552ed(%rip), %rcx     # 0x5ec5e
callq 0x6050
cmpl $-0x1, -0x1c(%rbp)
jne 0x99ab
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movl $0x1b, %esi
callq *%rax
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movl $0x25, %esi
callq *%rax
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movl $0x47, %esi
callq *%rax
jmp 0x99e3
movl $0x0, -0x34(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
andq $-0x3801, %rcx          # imm = 0xC7FF
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
andq $-0x100, %rcx
movq %rcx, 0x8(%rax)
movq -0x8(%rbp), %rax
movq $0x0, (%rax)
jmp 0x99e5
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
andq $-0x1c001, %rcx         # imm = 0xFFFE3FFF
movq %rcx, 0x8(%rax)
movl -0x1c(%rbp), %eax
addl $0x2, %eax
cmpl $0x0, %eax
jl 0x9a10
movl -0x1c(%rbp), %eax
addl $0x2, %eax
cmpl $0x8, %eax
jge 0x9a10
jmp 0x9a2f
leaq 0x552a4(%rip), %rdi     # 0x5ecbb
leaq 0x54fe3(%rip), %rsi     # 0x5ea01
movl $0x39f, %edx            # imm = 0x39F
leaq 0x55234(%rip), %rcx     # 0x5ec5e
callq 0x6050
movl -0x1c(%rbp), %eax
addl $0x2, %eax
shll $0xe, %eax
movslq %eax, %rcx
movq -0x8(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
cmpl $0x0, -0x2c(%rbp)
jle 0x9bb9
cmpl $0x2, -0x1c(%rbp)
je 0x9a59
jmp 0x9a78
leaq 0x55279(%rip), %rdi     # 0x5ecd9
leaq 0x54f9a(%rip), %rsi     # 0x5ea01
movl $0x3a7, %edx            # imm = 0x3A7
leaq 0x551eb(%rip), %rcx     # 0x5ec5e
callq 0x6050
cmpl $-0x1, -0x1c(%rbp)
jne 0x9ab4
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x9aaf
movq -0x10(%rbp), %rax
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rcx
movslq -0x38(%rbp), %rdx
movsbq (%rcx,%rdx), %rsi
callq *%rax
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x9a85
jmp 0x9bb7
movl -0x34(%rbp), %eax
addl -0x2c(%rbp), %eax
cmpl $0x5, %eax
jg 0x9ac1
jmp 0x9ae0
leaq 0x5521b(%rip), %rdi     # 0x5ece3
leaq 0x54f32(%rip), %rsi     # 0x5ea01
movl $0x3b4, %edx            # imm = 0x3B4
leaq 0x55183(%rip), %rcx     # 0x5ec5e
callq 0x6050
movl $0x0, -0x38(%rbp)
movl -0x38(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jge 0x9b59
movl -0x34(%rbp), %eax
addl -0x38(%rbp), %eax
cmpl $0x0, %eax
jne 0x9b1c
movq -0x28(%rbp), %rax
movslq -0x38(%rbp), %rcx
movsbl (%rax,%rcx), %eax
andl $0xff, %eax
movslq %eax, %rcx
movq -0x8(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
jmp 0x9b4c
movq -0x28(%rbp), %rax
movslq -0x38(%rbp), %rcx
movsbl (%rax,%rcx), %eax
andl $0xff, %eax
movl -0x34(%rbp), %edx
addl -0x38(%rbp), %edx
movl $0x4, %ecx
subl %edx, %ecx
shll $0x3, %ecx
shll %cl, %eax
movslq %eax, %rcx
movq -0x8(%rbp), %rax
orq (%rax), %rcx
movq %rcx, (%rax)
jmp 0x9b4e
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x9ae7
movl -0x2c(%rbp), %eax
addl -0x34(%rbp), %eax
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
jl 0x9b70
cmpl $0x8, -0x34(%rbp)
jge 0x9b70
jmp 0x9b8f
leaq 0x55183(%rip), %rdi     # 0x5ecfa
leaq 0x54e83(%rip), %rsi     # 0x5ea01
movl $0x3bc, %edx            # imm = 0x3BC
leaq 0x550d4(%rip), %rcx     # 0x5ec5e
callq 0x6050
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rcx
andq $-0x3801, %rcx          # imm = 0xC7FF
movq %rcx, 0x8(%rax)
movl -0x34(%rbp), %eax
shll $0xb, %eax
movslq %eax, %rcx
movq -0x8(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
jmp 0x9bb9
addq $0x60, %rsp
popq %rbp
retq
nop