// File: /workspace/github_c_makefile_star2_O1/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
movb $0x7f, 0xf(%rsp)
testq %rdi, %rdi
je 0xc011a
movq %rdi, %rbx
movq (%rdi), %rax
testq %rax, %rax
je 0xc011a
cmpq $0x0, 0x220(%rax)
je 0xc011a
cmpb $0x0, 0x2f0(%rax)
je 0xbffa6
movq 0x10(%rbx), %rcx
cmpq 0x38(%rax), %rcx
jae 0xc011f
cmpb $0x1, 0x3a8(%rax)
jne 0xbffd3
cmpq 0x30(%rax), %rcx
jne 0xbffd3
cmpb $0x0, 0x20(%rbx)
jne 0xbff31
movl 0x8(%rbx), %edx
movl $0x3, %esi
subl %edx, %esi
movl %esi, 0x8(%rbx)
testl $0xfffffffd, %edx       # imm = 0xFFFFFFFD
jne 0xc0138
leaq -0x1(%rcx), %rdx
movq %rdx, 0x10(%rbx)
cmpb $0x1, 0x3a9(%rax)
jne 0xc0100
cmpb $0x1, 0x29(%rax)
jne 0xbff6b
cmpq $0x0, 0x28(%rbx)
je 0xc013d
movq %rbx, %rdi
xorl %esi, %esi
callq 0xbf6bb
movq %rbx, %rdi
xorl %esi, %esi
callq 0xbfe27
movq (%rbx), %rax
movb $-0x1, %bpl
cmpq $0x2, 0x40(%rax)
jb 0xc00f7
cmpq $0x0, 0x30(%rbx)
je 0xc0142
movq %rbx, %rdi
movl $0x1, %esi
callq 0xbf6bb
movq %rbx, %rdi
movl $0x1, %esi
callq 0xbfe27
jmp 0xc00f7
movq %rbx, %rdi
callq 0xbf542
movl %eax, %ebp
cmpb $-0x1, %al
je 0xbffc9
movq (%rbx), %rax
movq 0x220(%rax), %rdi
movzbl %bpl, %esi
callq 0xb9d4b
movl %eax, %ebp
movb %bpl, 0xf(%rsp)
jmp 0xc00f7
cmpq 0x30(%rax), %rcx
jae 0xc0124
movq %rbx, %rdi
callq *0x110(%rax)
cmpb $-0x1, %al
je 0xc00a7
movl %eax, %ebp
movq $-0x1, 0x10(%rsp)
movq (%rbx), %rdi
cmpq $0x0, 0x1e0(%rdi)
je 0xc008a
movq 0x10(%rbx), %rdx
leaq 0x10(%rsp), %rsi
callq *0x150(%rdi)
testb %al, %al
je 0xc008a
movq (%rbx), %rax
movq 0x330(%rax), %rax
testq %rax, %rax
je 0xc0129
movq 0x10(%rsp), %rsi
cmpq %rsi, 0x8(%rax)
jbe 0xc0129
movl 0x10(%rax), %edx
cmpq $0x21, %rdx
jae 0xc0129
movq (%rax), %rdi
imulq %rdx, %rsi
callq 0xdda90
movzbl %al, %ecx
movq (%rbx), %rax
movzbl 0x360(%rax), %edx
cmpl %edx, %ecx
jae 0xc0133
movq 0x338(%rax), %rdx
movq 0x350(%rax), %rax
movzbl %bpl, %esi
movl %ecx, %ecx
addq (%rdx,%rsi,8), %rax
addq %rcx, %rax
jmp 0xc0098
movq (%rbx), %rcx
movzbl %bpl, %eax
addq 0x348(%rcx), %rax
movb (%rax), %al
movb %al, 0xf(%rsp)
cmpb $0x7f, %al
jne 0xc00ac
callq 0x2a8be
movb $-0x1, 0xf(%rsp)
movl 0x8(%rbx), %edi
cmpq $0x3, %rdi
ja 0xc012e
leaq 0x42714(%rip), %rax     # 0x1027d0
movslq (%rax,%rdi,4), %rcx
addq %rax, %rcx
jmpq *%rcx
incq 0x10(%rbx)
jmp 0xc00f2
incq 0x10(%rbx)
jmp 0xc00d5
decq 0x10(%rbx)
movb 0xf(%rsp), %al
cmpb $-0x1, %al
je 0xc00f2
movsbl %al, %esi
leaq 0xf(%rsp), %rdi
xorl %edx, %edx
callq 0xbe154
jmp 0xc00f2
decq 0x10(%rbx)
movb 0xf(%rsp), %bpl
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %rbp
retq
movb $-0x1, %bpl
cmpl $0x2, (%rax)
jne 0xc00f7
movq %rcx, 0x10(%rbx)
movq %rbx, %rdi
callq 0xbfe59
decq 0x10(%rbx)
jmp 0xc00f7
callq 0x2a9c5
callq 0x2a7dc
callq 0x2a815
callq 0x2a887
callq 0x2a8f7
callq 0x2a84e
callq 0x2a91a
callq 0x2a98c
callq 0x2a953