// File: /workspace/github_c_makefile_star2_O2/genometools[P]genometools/src/core/encseq.c
// Function: gt_encseq_reader_reinit_with_readmode
void gt_encseq_reader_reinit_with_readmode(GtEncseqReader *esr,
                                           const GtEncseq *encseq,
                                           GtReadmode readmode,
                                           GtUword startpos)
{
  gt_assert(esr != NULL && encseq != NULL);
  if (encseq != esr->encseq) {
    if (esr->encseq != NULL)
      gt_encseq_delete(esr->encseq);
    esr->encseq = gt_encseq_ref((GtEncseq*) encseq);
  }
  gt_assert(esr->encseq);

  /* translate reverse positions into forward positions */
  if (GT_ISDIRREVERSE(readmode))
    startpos = GT_REVERSEPOS(encseq->logicaltotallength, startpos);
  esr->originalreadmode = readmode;

  /* if inside virtual mirror sequence, adjust start position and reading
     direction */
  if (encseq->hasmirror) {
    if (startpos >= encseq->totallength) {
      esr->startedonmiddle = (startpos == encseq->totallength);
      startpos = GT_REVERSEPOS(encseq->totallength,
                               startpos - encseq->totallength - 1);
      switch (readmode) {
        case GT_READMODE_REVERSE:
          if (esr->startedonmiddle)
            readmode = GT_READMODE_REVERSE;
          else
            gt_readmode_invert(readmode);
          break;
        case GT_READMODE_REVCOMPL:
          if (esr->startedonmiddle)
            readmode = GT_READMODE_REVCOMPL;
          else
            gt_readmode_invert(readmode);
          break;
        default:
          gt_readmode_invert(readmode);
          break;
      }
    }
  }
  gt_assert(startpos <= encseq->totallength);
  esr->readmode = readmode;
  esr->currentpos = startpos;
  if (encseq->accesstype_via_utables) {
    /* Do not need this in once all is done by wildcards */
    if (encseq->has_wildcardranges) {
      if (esr->wildcardrangestate == NULL) {
        esr->wildcardrangestate =
          gt_calloc((size_t) 1, sizeof (*esr->wildcardrangestate));
      }
      binpreparenextrangeGtEncseqReader(esr, SWtable_wildcardrange);
#ifdef GT_RANGEDEBUG
      printf("wildcardranges: start advance "
             "at ("GT_WU", "GT_WU") in page "GT_WU"\n",
                       esr->wildcardrangestate->firstcell,
                       esr->wildcardrangestate->lastcell,
                       esr->wildcardrangestate->nextpage);
#endif
      advancerangeGtEncseqReader(esr, SWtable_wildcardrange);
    }
    if (esr->encseq->numofdbsequences > 1UL) {
      gt_assert(esr->encseq->satsep != GT_ACCESS_TYPE_UNDEFINED);
      if (esr->ssptabstate == NULL) {
        esr->ssptabstate =
          gt_calloc((size_t) 1, sizeof (*esr->ssptabstate));
      }
      binpreparenextrangeGtEncseqReader(esr, SWtable_ssptab);
#ifdef GT_RANGEDEBUG
      printf("ssptab: start advance at ("GT_WU", "GT_WU") in page "GT_WU"\n",
                       esr->ssptabstate->firstcell,
                       esr->ssptabstate->lastcell,
                       esr->ssptabstate->nextpage);
#endif
      advancerangeGtEncseqReader(esr, SWtable_ssptab);
    }
  }
  else {
    if (esr->wildcardrangestate != NULL) {
      gt_free(esr->wildcardrangestate);
      esr->wildcardrangestate = NULL;
    }
    if (esr->ssptabstate != NULL) {
      gt_free(esr->ssptabstate);
      esr->ssptabstate = NULL;
    }
    if (encseq->sat == GT_ACCESS_TYPE_EQUALLENGTH) {
      if (issinglepositioninspecialrangeViaequallength(esr->encseq, startpos)) {
        esr->nextseparatorpos = startpos;
      }
      else {
        GtUword seqnum = (startpos + 1)/
                               (encseq->equallength.valueunsignedlong + 1);
        if (!GT_ISDIRREVERSE(esr->readmode)) {
          esr->nextseparatorpos = encseq->equallength.valueunsignedlong +
                                  seqnum *
                                  (encseq->equallength.valueunsignedlong + 1);
        }
        else {
          if (seqnum > 0) {
            esr->nextseparatorpos = encseq->equallength.valueunsignedlong +
                                    (seqnum-1) *
                                    (encseq->equallength.valueunsignedlong + 1);
          }
          else {
            esr->nextseparatorpos = 0;
          }
        }
      }
    }
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
testq %rdi, %rdi
je 0xa3b22
movq %rsi, %r14
testq %rsi, %rsi
je 0xa3b22
movq %rcx, %r12
movl %edx, %ebp
movq %rdi, %rbx
movq (%rdi), %rdi
cmpq %r14, %rdi
je 0xa3969
testq %rdi, %rdi
je 0xa395b
callq 0xa4fe9
movq %r14, %rdi
callq 0xa56aa
movq %r14, (%rbx)
movq %r14, %rdi
movl %ebp, %eax
andl $-0x3, %eax
cmpl $0x1, %eax
jne 0xa397a
notq %r12
addq 0x38(%r14), %r12
movl %ebp, 0xc(%rbx)
movq 0x30(%r14), %rax
cmpq %r12, %rax
setbe %cl
andb 0x3a8(%r14), %cl
cmpb $0x1, %cl
jne 0xa39b8
movq %rax, %rcx
subq %r12, %rcx
sete 0x20(%rbx)
leaq (%rcx,%rax), %r15
cmpl $0x3, %ebp
je 0xa39bd
cmpl $0x1, %ebp
jne 0xa39ca
xorl %ebp, %ebp
cmpq %r12, %rax
setne %bpl
incl %ebp
jmp 0xa39d1
movq %r12, %r15
jmp 0xa39d1
xorl %ecx, %ecx
cmpq %r12, %rax
sete %cl
leal (%rcx,%rcx,2), %ebp
jmp 0xa39d1
pushq $0x3
popq %rcx
subl %ebp, %ecx
movl %ecx, %ebp
cmpq %rax, %r15
ja 0xa3b50
movl %ebp, 0x8(%rbx)
movq %r15, 0x10(%rbx)
cmpb $0x1, 0x3a9(%r14)
jne 0xa3a85
cmpb $0x1, 0x29(%r14)
jne 0xa3a2f
cmpq $0x0, 0x28(%rbx)
jne 0xa3a18
leaq 0x48196(%rip), %rdx     # 0xebb9a
pushq $0x1
popq %rdi
pushq $0x40
popq %rsi
movl $0xc1a, %ecx            # imm = 0xC1A
callq 0xce9a
movq %rax, 0x28(%rbx)
movq %rbx, %rdi
xorl %esi, %esi
callq 0xa2bb3
movq %rbx, %rdi
xorl %esi, %esi
callq 0xa32f8
movq (%rbx), %rdi
cmpq $0x2, 0x40(%rdi)
jb 0xa3b19
cmpl $0x7, 0x4(%rdi)
je 0xa3b88
cmpq $0x0, 0x30(%rbx)
jne 0xa3a66
leaq 0x48148(%rip), %rdx     # 0xebb9a
pushq $0x1
popq %rdi
pushq $0x40
popq %rsi
movl $0xc2a, %ecx            # imm = 0xC2A
callq 0xce9a
movq %rax, 0x30(%rbx)
pushq $0x1
popq %rbp
movq %rbx, %rdi
movl %ebp, %esi
callq 0xa2bb3
movq %rbx, %rdi
movl %ebp, %esi
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0xa32f8
movq 0x28(%rbx), %rdi
testq %rdi, %rdi
je 0xa3aa4
leaq 0x48105(%rip), %rsi     # 0xebb9a
movl $0xc38, %edx            # imm = 0xC38
callq 0xd249
andq $0x0, 0x28(%rbx)
movq 0x30(%rbx), %rdi
testq %rdi, %rdi
je 0xa3ac3
leaq 0x480e6(%rip), %rsi     # 0xebb9a
movl $0xc3c, %edx            # imm = 0xC3C
callq 0xd249
andq $0x0, 0x30(%rbx)
cmpl $0x2, (%r14)
jne 0xa3b19
movq (%rbx), %rdi
movq %r15, %rsi
callq 0xa228c
testb %al, %al
je 0xa3ade
movq %r15, 0x18(%rbx)
jmp 0xa3b19
incq %r15
movq 0x1f0(%r14), %rcx
leaq 0x1(%rcx), %rsi
movq %r15, %rax
xorl %edx, %edx
divq %rsi
movl 0x8(%rbx), %edx
orl $0x2, %edx
cmpl $0x3, %edx
jne 0xa3b0e
cmpq %r15, %rsi
jbe 0xa3b0b
andq $0x0, 0x18(%rbx)
jmp 0xa3b19
decq %rax
imulq %rsi, %rax
addq %rcx, %rax
movq %rax, 0x18(%rbx)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq 0x8a48f(%rip), %rax     # 0x12dfb8
movq (%rax), %rdi
leaq 0x26533(%rip), %rsi     # 0xca066
leaq 0x48787(%rip), %rdx     # 0xec2c1
leaq 0x4879e(%rip), %rcx     # 0xec2df
leaq 0x48052(%rip), %r8      # 0xebb9a
movl $0xbeb, %r9d            # imm = 0xBEB
jmp 0xa3b7c
movq 0x8a461(%rip), %rax     # 0x12dfb8
movq (%rax), %rdi
leaq 0x26505(%rip), %rsi     # 0xca066
leaq 0x4879d(%rip), %rdx     # 0xec305
leaq 0x48770(%rip), %rcx     # 0xec2df
leaq 0x48024(%rip), %r8      # 0xebb9a
movl $0xc12, %r9d            # imm = 0xC12
xorl %eax, %eax
callq 0xb8c0
callq 0xb300
movq 0x8a429(%rip), %rax     # 0x12dfb8
movq (%rax), %rdi
leaq 0x264cd(%rip), %rsi     # 0xca066
leaq 0x48785(%rip), %rdx     # 0xec325
leaq 0x48738(%rip), %rcx     # 0xec2df
leaq 0x47fec(%rip), %r8      # 0xebb9a
movl $0xc27, %r9d            # imm = 0xC27
jmp 0xa3b7c