// File: /workspace/github_cpp_makefile_star2_O3/AlgoLab[P]bwt-lcp-parallel/bwt_lcp.cpp
// Function: compute_interleave_LCP_segment(base_env_t&, bfv_env_t&, unsigned long, unsigned long, unsigned char, std::vector<unsigned int, std::allocator<unsigned int>> const&, unsigned int)
void compute_interleave_LCP_segment(
                                    base_env_t& base_env,
                                    bfv_env_t& bfv_env,
                                    const luint_t segm_b, const luint_t segm_e,
                                    const strlen_t p,
                                    const std::vector<strnum_t>& Qppos,
                                    unsigned idx
) {
  std::cout << ".";
  const luint_t tot = segm_e - segm_b;
  const strlen_t k = base_env.k;
  auto& E = base_env.E;

  auto& LCP = bfv_env.LCP;
  std::vector<strnum_t> Qppos_int = Qppos;

  mmap_reader_t<strlen_t> IX0(base_env.IX_names[(p-1)%2]);
  mmap_writer_t<strlen_t, ALPHSIZE> IX1(base_env.IX_names[p%2]);
  qp_readers_t Qp, Qpbis;
  for (strlen_t l = p+1; l <= k+1; ++l) {
    Qp.emplace_back(base_env.Qp[l-p-1].cloneAndSeek(Qppos[l-1]));
    Qpbis.emplace_back(base_env.Qp[l-p-1].cloneAndSeek(Qppos[l-1]));
  }
  luint_t Lcount[ALPHSIZE];
  fill_with_0<luint_t, ALPHSIZE>(Lcount);
  luint_t Lpos[ALPHSIZE];
  luint_t b = segm_b;
  bool has_pseg_wider_than_1 = false;
  bfv_env.end_pos.clear();
  bfv_env.end_pos_Qp.clear();
  IX0.seek(segm_b);
  IX1.seek(ALPHSIZE-1, segm_b);
  for (luint_t i = segm_b; i < segm_e; ++i) {
    const strlen_t IX0i = IX0.read();
    const enc_nucl_t c = (IX0i < p) ? 0 : Qp[IX0i-p].read();
    ///printf("p=%d i=%lu IX=%d c=%x L%x=%d\n", p, i, IX0i, c, c, IX0i);
    ++Qppos_int[IX0i];
    ++Lcount[c];
    if (E[i]) {
      ///printf("finished segment at pos %lu\n", i);
      if (i+1 >= base_env.midpoints[idx-1]) {
        bfv_env.end_pos.push_back(i + 1);
        bfv_env.end_pos_Qp.push_back(Qppos_int);
        ++idx;
      }
      if (b==i) {
        // Special case of a single-element segment
        if (IX0i >= p) Qpbis[IX0i-p].skip();  // advance Qpbis as well
        IX1.write(ALPHSIZE-1, IX0i);
        Lcount[c] = 0;
        b = i + 1;
      } else {
        const bool this_has_pseg_wider_than_1 = compute_Lpos(Lpos, b, Lcount);
        has_pseg_wider_than_1 |= this_has_pseg_wider_than_1;
        for (enc_nucl_t sigma = 0; sigma<ALPHSIZE; ++sigma) {
          if (Lcount[sigma] > 0) {
            const luint_t new_e = Lpos[sigma]+Lcount[sigma]-1-segm_b;
            ///printf("ending pos for sigma=%d in idx=%lu\n", sigma, Lpos[sigma]+Lcount[sigma]-1);
            if ((new_e < MARGIN) | (tot-new_e < MARGIN)) {
              std::lock_guard<std::mutex> lg(base_env.Emutex);
              E[segm_b+new_e] = true;
            } else {
              E[segm_b+new_e] = true;
            }
          }
        }
        if (this_has_pseg_wider_than_1) {
          update_LCP(LCP, p, Lpos[1], Lcount);
        }
        IX0.seek(b);
        IX1.seek(Lpos);
        for (luint_t r = b; r <= i; ++r) {
          const strlen_t IX0r = IX0.read();
          const enc_nucl_t cr = (IX0r < p) ? 0 : Qpbis[IX0r-p].read();
          ///printf("*p=%d i=%lu IX=%d c=%x L%x=%d\n", p, r, IX0r, cr, cr, IX0r);
          IX1.write(cr, IX0r);
        }
        fill_with_0<luint_t, ALPHSIZE>(Lcount);
        b = i + 1;
      }
    }
  }
  bfv_env.has_pseg_wider_than_1 = has_pseg_wider_than_1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1e8, %rsp            # imm = 0x1E8
movq %r9, %rbx
movl %r8d, %r14d
movq %rcx, 0x30(%rsp)
movq %rdx, 0x48(%rsp)
movq %rsi, 0x10(%rsp)
movq %rdi, %r15
movq 0xb117(%rip), %rdi      # 0xdfd0
leaq 0x63d1(%rip), %rsi      # 0x9291
movl $0x1, %edx
callq 0x2290
movzbl (%r15), %ebp
leaq 0x98(%rsp), %rdi
movq %rbx, %rsi
callq 0x5b38
movq 0x8(%r15), %rax
leal -0x1(%r14), %ecx
movzwl %cx, %ecx
shrl $0xf, %ecx
addl %r14d, %ecx
decl %ecx
andl $-0x2, %ecx
negl %ecx
addl %r14d, %ecx
decl %ecx
movswq %cx, %rsi
shlq $0x5, %rsi
addq (%rax), %rsi
leaq 0xf8(%rsp), %rdi
callq 0x5bb8
movq %r15, 0x8(%rsp)
movq 0x8(%r15), %rax
movl %r14d, %esi
andl $0x1, %esi
shll $0x5, %esi
addq (%rax), %rsi
leaq 0x150(%rsp), %rdi
xorl %edx, %edx
callq 0x5bfc
xorps %xmm0, %xmm0
movaps %xmm0, 0xb0(%rsp)
xorl %eax, %eax
movq %rax, 0xc0(%rsp)
movq %rax, 0x90(%rsp)
movaps %xmm0, 0x80(%rsp)
incl %ebp
leal 0x1(%r14), %eax
movzbl %al, %eax
movl %ebp, (%rsp)
cmpl %eax, %ebp
movq %r14, 0x40(%rsp)
jb 0x3015
movl %r14d, %r13d
notl %r13d
leal 0x2(%r14), %ebp
leaq 0x50(%rsp), %r15
leal (%rax,%r13), %ecx
movslq %ecx, %rcx
leaq (%rcx,%rcx,4), %r12
shlq $0x3, %r12
movq 0x8(%rsp), %rcx
movq 0x18(%rcx), %rsi
addq %r12, %rsi
movslq %eax, %r14
movq (%rbx), %rax
movl -0x4(%rax,%r14,4), %edx
movq %r15, %rdi
callq 0x5cac
leaq 0xb0(%rsp), %rdi
movq %r15, %rsi
callq 0x5c54
decq %r14
movq %r15, %rdi
callq 0x5cf8
movq 0x8(%rsp), %rax
addq 0x18(%rax), %r12
movq (%rbx), %rax
movl (%rax,%r14,4), %edx
movq %r15, %rdi
movq %r12, %rsi
callq 0x5cac
leaq 0x80(%rsp), %rdi
movq %r15, %rsi
callq 0x5c54
movq 0x40(%rsp), %r14
movq %r15, %rdi
callq 0x5cf8
movzbl %bpl, %eax
leal 0x1(%rax), %ebp
cmpl %eax, (%rsp)
jae 0x2f84
xorps %xmm0, %xmm0
movaps %xmm0, 0x70(%rsp)
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x50(%rsp)
movq 0x10(%rsp), %rbx
movq 0x30(%rbx), %rax
cmpq %rax, 0x38(%rbx)
je 0x303a
movq %rax, 0x38(%rbx)
leaq 0x48(%rbx), %rdi
movq 0x48(%rbx), %rsi
movq %rdi, 0xd0(%rsp)
callq 0x7920
leaq 0xf8(%rsp), %rdi
movq 0x48(%rsp), %r15
movq %r15, %rsi
callq 0x5d2a
leaq 0x150(%rsp), %rdi
movl $0x5, %esi
movq %r15, %rdx
callq 0x5dc6
cmpq 0x30(%rsp), %r15
jae 0x3496
movl 0x220(%rsp), %eax
movq %rax, 0x20(%rsp)
leaq 0x30(%rbx), %rax
movq %rax, 0xc8(%rsp)
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
movq 0x8(%rsp), %rax
addq $0x68, %rax
movq $0x0, 0x18(%rsp)
leaq 0xf8(%rsp), %rbx
addq $0x3f, %rcx
movq %rcx, 0x28(%rsp)
leaq 0x150(%rsp), %r13
movq %r15, %r12
movq %rax, 0xe0(%rsp)
movq %r15, (%rsp)
movq %rbx, %rdi
callq 0x5e6a
movl %eax, %ebp
movzbl %al, %r15d
cmpb %r14b, %r15b
jae 0x30f7
xorl %edx, %edx
jmp 0x3117
movl %r15d, %eax
subl %r14d, %eax
cltq
leaq (%rax,%rax,4), %rdi
shlq $0x3, %rdi
addq 0xb0(%rsp), %rdi
callq 0x5e6a
movzbl %al, %edx
movq 0x98(%rsp), %rax
movl %r15d, %ecx
incl (%rax,%rcx,4)
movq %rdx, 0xd8(%rsp)
incq 0x50(%rsp,%rdx,8)
movq (%rsp), %r8
leaq 0x3f(%r8), %rax
testq %r8, %r8
cmovnsq %r8, %rax
sarq $0x6, %rax
shlq $0x3, %rax
movq 0x8(%rsp), %rsi
addq 0x40(%rsi), %rax
movq %r8, %rcx
andq 0x28(%rsp), %rcx
xorl %edx, %edx
movabsq $-0x8000000000000000, %rdi # imm = 0x8000000000000000
cmpq %rdi, %rcx
setbe %dl
movq -0x8(%rax,%rdx,8), %rax
leaq 0x1(%r8), %rdx
btq %r8, %rax
jae 0x31b5
movq 0x38(%rsi), %rax
movq 0x20(%rsp), %rcx
decl %ecx
cmpq (%rax,%rcx,8), %rdx
movq %rdx, 0x38(%rsp)
jb 0x31f3
movq %rdx, 0xf0(%rsp)
movq 0x10(%rsp), %rax
movq 0x38(%rax), %rsi
cmpq 0x40(%rax), %rsi
je 0x31bd
movq %rdx, (%rsi)
addq $0x8, %rsi
movq %rsi, 0x38(%rax)
jmp 0x31d2
movq %rdx, %r15
jmp 0x347d
movq 0xc8(%rsp), %rdi
leaq 0xf0(%rsp), %rdx
callq 0x796a
movq 0xd0(%rsp), %rdi
leaq 0x98(%rsp), %rsi
callq 0x5ee6
movq 0x20(%rsp), %rax
incl %eax
movq %rax, 0x20(%rsp)
cmpq (%rsp), %r12
jne 0x3261
cmpb %r14b, %bpl
jb 0x3236
movl %r15d, %eax
subl %r14d, %eax
movslq %eax, %rcx
movq 0x80(%rsp), %rax
leaq (%rcx,%rcx,4), %rcx
movq 0x10(%rax,%rcx,8), %rsi
incq %rsi
movq %rsi, 0x10(%rax,%rcx,8)
cmpq $0x400000, %rsi         # imm = 0x400000
jb 0x3236
leaq (%rax,%rcx,8), %rdi
addq 0x8(%rdi), %rsi
callq 0x5d2a
movq %r13, %rdi
movl $0x5, %esi
movl %r15d, %edx
callq 0x5f12
movq 0xd8(%rsp), %rax
movq $0x0, 0x50(%rsp,%rax,8)
movq 0x38(%rsp), %r15
jmp 0x347a
movq %r12, 0x120(%rsp)
xorl %eax, %eax
movq %r12, %rcx
addq 0x50(%rsp,%rax,8), %rcx
movq %rcx, 0x128(%rsp,%rax,8)
incq %rax
cmpq $0x5, %rax
jne 0x326e
movl $0x1, %eax
xorl %ebp, %ebp
cmpq $0x2, 0x50(%rsp,%rax,8)
setae %cl
orb %cl, %bpl
incq %rax
cmpq $0x6, %rax
jne 0x328b
movl %ebp, %eax
andb $0x1, %al
movq 0x18(%rsp), %rcx
orb %al, %cl
movq %rcx, 0x18(%rsp)
xorl %r14d, %r14d
movq %r12, 0xe8(%rsp)
movq 0x50(%rsp,%r14,8), %rax
testq %rax, %rax
je 0x33bc
movq 0x120(%rsp,%r14,8), %rcx
leaq (%rax,%rcx), %r15
decq %r15
movq %r15, %rax
subq 0x48(%rsp), %rax
cmpq $0x40, %rax
setae %al
movq 0x30(%rsp), %rcx
subq %r15, %rcx
cmpq $0x40, %rcx
setae %cl
testb %cl, %al
jne 0x3376
movq %r13, %r12
movq %rbx, %r13
movq 0xe0(%rsp), %rbx
movq %rbx, %rdi
callq 0x2320
testl %eax, %eax
jne 0x34fe
leaq 0x3f(%r15), %rax
testq %r15, %r15
cmovnsq %r15, %rax
sarq $0x6, %rax
shlq $0x3, %rax
movq 0x8(%rsp), %rcx
addq 0x40(%rcx), %rax
movq %r15, %rcx
andq 0x28(%rsp), %rcx
xorl %edx, %edx
movabsq $-0x8000000000000000, %rsi # imm = 0x8000000000000000
cmpq %rsi, %rcx
setbe %dl
movl $0x1, %esi
movl %r15d, %ecx
shlq %cl, %rsi
orq %rsi, -0x8(%rax,%rdx,8)
movq %rbx, %rdi
callq 0x21c0
movq %r13, %rbx
movq %r12, %r13
movq 0xe8(%rsp), %r12
jmp 0x33bc
leaq 0x3f(%r15), %rax
testq %r15, %r15
cmovnsq %r15, %rax
sarq $0x6, %rax
shlq $0x3, %rax
movq 0x8(%rsp), %rcx
addq 0x40(%rcx), %rax
movq %r15, %rcx
andq 0x28(%rsp), %rcx
xorl %edx, %edx
movabsq $-0x8000000000000000, %rsi # imm = 0x8000000000000000
cmpq %rsi, %rcx
setbe %dl
movl $0x1, %esi
movl %r15d, %ecx
shlq %cl, %rsi
orq %rsi, -0x8(%rax,%rdx,8)
incq %r14
cmpq $0x6, %r14
jne 0x32bb
testb $0x1, %bpl
movq 0x40(%rsp), %r14
je 0x33ef
movq 0x128(%rsp), %rdx
movzbl %r14b, %esi
movq 0x10(%rsp), %rdi
leaq 0x50(%rsp), %rcx
callq 0x2d65
movq %rbx, %rdi
movq %r12, %rsi
callq 0x5d2a
xorl %r15d, %r15d
movq 0x120(%rsp,%r15,8), %rdx
movq %r13, %rdi
movl %r15d, %esi
callq 0x5dc6
incq %r15
cmpq $0x6, %r15
jne 0x33fd
cmpq (%rsp), %r12
movq 0x38(%rsp), %r15
ja 0x3468
movq %rbx, %rdi
callq 0x5e6a
xorl %esi, %esi
movzbl %al, %ebp
cmpb %r14b, %al
jb 0x3455
movl %ebp, %eax
subl %r14d, %eax
cltq
leaq (%rax,%rax,4), %rdi
shlq $0x3, %rdi
addq 0x80(%rsp), %rdi
callq 0x5e6a
movzbl %al, %esi
movq %r13, %rdi
movl %ebp, %edx
callq 0x5f12
incq %r12
cmpq (%rsp), %r12
jbe 0x3424
xorps %xmm0, %xmm0
movaps %xmm0, 0x70(%rsp)
movaps %xmm0, 0x60(%rsp)
movaps %xmm0, 0x50(%rsp)
movq %r15, %r12
cmpq 0x30(%rsp), %r15
jne 0x30dc
movq 0x18(%rsp), %rax
andb $0x1, %al
movq 0x10(%rsp), %rbx
jmp 0x3498
xorl %eax, %eax
movb %al, 0x29(%rbx)
leaq 0x80(%rsp), %rdi
callq 0x5fbe
leaq 0xb0(%rsp), %rdi
callq 0x5fbe
leaq 0x150(%rsp), %rdi
callq 0x6006
leaq 0xf8(%rsp), %rdi
callq 0x5cf8
movq 0x98(%rsp), %rdi
testq %rdi, %rdi
je 0x34ec
movq 0xa8(%rsp), %rsi
subq %rdi, %rsi
callq 0x2260
addq $0x1e8, %rsp            # imm = 0x1E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %eax, %edi
callq 0x2150
movq %rax, %rbx
jmp 0x3552
movq %rax, %rbx
jmp 0x355f
jmp 0x3528
jmp 0x3528
jmp 0x3528
jmp 0x3519
jmp 0x3528
movq %rax, %rbx
leaq 0x50(%rsp), %rdi
callq 0x5cf8
jmp 0x352b
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x5fbe
leaq 0xb0(%rsp), %rdi
callq 0x5fbe
leaq 0x150(%rsp), %rdi
callq 0x6006
leaq 0xf8(%rsp), %rdi
callq 0x5cf8
movq 0x98(%rsp), %rdi
testq %rdi, %rdi
je 0x357c
movq 0xa8(%rsp), %rsi
subq %rdi, %rsi
callq 0x2260
movq %rbx, %rdi
callq 0x23d0