// File: /workspace/github_c_makefile_star2_O3/genometools[P]genometools/src/core/encseq.c
// Function: gt_encseq_reader_next_decoded_char
char gt_encseq_reader_next_decoded_char(GtEncseqReader *esr)
{
  char cc = GT_UNDEF_CHAR;
  gt_assert(esr && esr->encseq && esr->encseq->alpha);
  if (!esr->encseq->has_exceptiontable) {
    /* no lossless support available, we need to do simple decoding */
    GtUchar mycc = gt_encseq_reader_next_encoded_char(esr);
    if (mycc != (GtUchar) GT_SEPARATOR)
      cc = gt_alphabet_decode(esr->encseq->alpha, mycc);
    else
      cc = (char) mycc;
    return cc;
  } else {
    GtUchar ccc;
    gt_assert(esr->encseq
              && esr->currentpos < esr->encseq->logicaltotallength);
    /* if we have mirroring enabled, we need to check whether we cross the
       boundary between real and virtual sequences, turn around if necessary */
    if (esr->encseq->hasmirror && esr->currentpos == esr->encseq->totallength) {
      if (!esr->startedonmiddle) {
        /* only turn around if we arrived from complementary side */
        gt_readmode_invert(esr->readmode);
        /* from now on, we can only go backwards on the original sequence! */
        gt_assert(GT_ISDIRREVERSE(esr->readmode));
      }
      /* go back */
      esr->currentpos--;
      if (esr->encseq->accesstype_via_utables) {
        /* prepare esr for directional change */
        if (esr->encseq->has_wildcardranges) {
          gt_assert(esr->wildcardrangestate != NULL);
          binpreparenextrangeGtEncseqReader(esr, SWtable_wildcardrange);
          advancerangeGtEncseqReader(esr, SWtable_wildcardrange);
        }
        if (esr->encseq->numofdbsequences > 1UL) {
          gt_assert(esr->ssptabstate != NULL);
          binpreparenextrangeGtEncseqReader(esr, SWtable_ssptab);
          advancerangeGtEncseqReader(esr, SWtable_ssptab);
        }
      }
      else {
        if (esr->encseq->sat == GT_ACCESS_TYPE_EQUALLENGTH) {
          esr->currentpos++;
          singlepositioninseparatorViaequallength_updatestate(esr);
          esr->currentpos--;
        }
      }
      return (char) GT_SEPARATOR;
    }
    gt_assert(esr && esr->currentpos < esr->encseq->totallength);

    ccc = esr->encseq->seqdeliverchar(esr);
    if (ccc != (GtUchar) GT_SEPARATOR) {
      GtUword mappos = GT_UNDEF_UWORD;
      if (esr->encseq->specialcharinfo.realexceptionranges > 0UL
            && esr->encseq->getexceptionmapping(esr->encseq,
                                                &mappos, esr->currentpos)) {
        /* if the character at this position is not the most frequent in
           its class, look up its exception */
        unsigned char subalphcode = (unsigned char)
                                bitpackarray_get_uint32(esr->encseq->exceptions,
                                                        (BitOffset) mappos);
        gt_assert(subalphcode < esr->encseq->maxsubalphasize);
        /* and map it back to the original character */
        cc = esr->encseq->allchars[esr->encseq->classstartpositions[(int) ccc]
                                     + subalphcode];
      } else {
        /* otherwise return most frequent character */
        cc = esr->encseq->maxchars[(int) ccc];
      }
      gt_assert(cc != GT_UNDEF_CHAR);
    } else {
      cc = (char) GT_SEPARATOR;
    }
    switch (esr->readmode) {
      case GT_READMODE_FORWARD:
        esr->currentpos++;
        return cc;
      case GT_READMODE_REVERSE:
        esr->currentpos--;
        return cc;
      case GT_READMODE_COMPL: /* only works with dna */
        esr->currentpos++;
        if (cc != (char) GT_SEPARATOR)
          (void) gt_complement(&cc, cc, NULL);
        return cc;
      case GT_READMODE_REVCOMPL: /* only works with dna */
        esr->currentpos--;
        if (cc != (char) GT_SEPARATOR)
          (void) gt_complement(&cc, cc, NULL);
        return cc;
      default:
        fprintf(stderr, "gt_encseq_next_encoded_char: "
                       "readmode %d not implemented\n", (int) esr->readmode);
        exit(GT_EXIT_PROGRAMMING_ERROR);
    }
  }
}

// Assembly:
pushq %rbp
pushq %rbx
subq $0x18, %rsp
testq %rdi, %rdi
je 0xc11bf
movq %rdi, %rbx
movq (%rdi), %rax
testq %rax, %rax
je 0xc11bf
cmpq $0x0, 0x220(%rax)
je 0xc11bf
cmpb $0x0, 0x2f0(%rax)
je 0xc1044
movq 0x10(%rbx), %rcx
cmpq 0x38(%rax), %rcx
jae 0xc11c4
movq 0x30(%rax), %rdx
cmpq %rdx, %rcx
sete %sil
andb 0x3a8(%rax), %sil
cmpb $0x1, %sil
jne 0xc106c
cmpb $0x0, 0x20(%rbx)
jne 0xc0fcf
movl 0x8(%rbx), %edx
movl $0x3, %esi
subl %edx, %esi
movl %esi, 0x8(%rbx)
testl $0xfffffffd, %edx       # imm = 0xFFFFFFFD
jne 0xc11d3
leaq -0x1(%rcx), %rdx
movq %rdx, 0x10(%rbx)
cmpb $0x1, 0x3a9(%rax)
jne 0xc1126
cmpb $0x1, 0x29(%rax)
jne 0xc100c
cmpq $0x0, 0x28(%rbx)
je 0xc11d8
movq %rbx, %rdi
xorl %esi, %esi
callq 0xc06cb
movq %rbx, %rdi
xorl %esi, %esi
callq 0xc0ec5
movq (%rbx), %rax
movb $-0x1, %bpl
cmpq $0x2, 0x40(%rax)
jb 0xc11b6
cmpq $0x0, 0x30(%rbx)
je 0xc11dd
movq %rbx, %rdi
movl $0x1, %esi
callq 0xc06cb
movq %rbx, %rdi
movl $0x1, %esi
callq 0xc0ec5
jmp 0xc11b6
movq %rbx, %rdi
callq 0xc054e
cmpb $-0x1, %al
je 0xc11b3
movq (%rbx), %rcx
movq 0x220(%rcx), %rdi
movzbl %al, %esi
addq $0x18, %rsp
popq %rbx
popq %rbp
jmp 0xbae5f
cmpq %rdx, %rcx
jae 0xc11c9
movq %rbx, %rdi
callq *0x110(%rax)
cmpb $-0x1, %al
je 0xc115e
movl %eax, %ebp
movq $-0x1, 0x10(%rsp)
movq (%rbx), %rdi
cmpq $0x0, 0x1e0(%rdi)
je 0xc1140
movq 0x10(%rbx), %rdx
leaq 0x10(%rsp), %rsi
callq *0x150(%rdi)
movq (%rbx), %rdi
testb %al, %al
je 0xc1140
movq 0x330(%rdi), %rax
testq %rax, %rax
je 0xc11ce
movq 0x10(%rsp), %rsi
cmpq %rsi, 0x8(%rax)
jbe 0xc11ce
movl 0x10(%rax), %edx
cmpq $0x21, %rdx
jae 0xc11ce
movq (%rax), %rdi
imulq %rdx, %rsi
callq 0xde1d4
movzbl %al, %ecx
movq (%rbx), %rax
movzbl 0x360(%rax), %edx
cmpl %edx, %ecx
jae 0xc11e7
movq 0x338(%rax), %rdx
movq 0x350(%rax), %rax
movzbl %bpl, %esi
movl %ecx, %ecx
addq (%rdx,%rsi,8), %rax
addq %rcx, %rax
jmp 0xc114b
movb $-0x1, %bpl
cmpl $0x2, (%rax)
jne 0xc11b6
movq %rcx, 0x10(%rbx)
movq %rbx, %rdi
callq 0xc0ef7
jmp 0xc1185
movzbl %bpl, %eax
addq 0x348(%rdi), %rax
movb (%rax), %bpl
movb %bpl, 0xf(%rsp)
cmpb $0x7f, %bpl
jne 0xc1166
callq 0x2a6c3
movb $-0x1, 0xf(%rsp)
movb $-0x1, %bpl
movl 0x8(%rbx), %edi
cmpq $0x3, %rdi
ja 0xc11e2
leaq 0x415ca(%rip), %rax     # 0x102740
movslq (%rax,%rdi,4), %rcx
addq %rax, %rcx
jmpq *%rcx
incq 0x10(%rbx)
jmp 0xc11b6
decq 0x10(%rbx)
jmp 0xc11b6
incq 0x10(%rbx)
jmp 0xc1195
decq 0x10(%rbx)
cmpb $-0x1, %bpl
je 0xc11b3
movsbl %bpl, %esi
leaq 0xf(%rsp), %rbx
movq %rbx, %rdi
xorl %edx, %edx
callq 0xbf1e4
movb (%rbx), %bpl
jmp 0xc11b6
movb $-0x1, %bpl
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %rbp
retq
callq 0x2a7ca
callq 0x2a5e1
callq 0x2a61a
callq 0x2a68c
callq 0x2a71f
callq 0x2a791
callq 0x2a758
callq 0x2a6fc
callq 0x2a653