// File: /workspace/github_cpp_makefile_star2_O2/chhylp123[P]hifiasm/Correct.cpp
// Function: gen_single_khit(Candidates_list*, long, long, long, long, long, long, long, long, long, long)
int64_t gen_single_khit(Candidates_list *cl, int64_t ch_n, int64_t h_khit, int64_t mode, int64_t qs, int64_t qe, int64_t ts, int64_t te, int64_t max_skip, int64_t max_iter, int64_t rid)
{
    // if(ch_n != 3 || mode != 0 || qs != 171728 || qe != 172258) return 0;
    k_mer_hit *ch_a = cl->list + cl->length; int64_t k, i, j, occ, m, ncn, prefix, suffix, srt = 1;
    prefix = suffix = 0;
    if(mode == 0 || mode == 2) suffix = 1;
    if(mode == 0 || mode == 1) prefix = 1;
    // if(ch_n == 2 && mode == 2 && qe - qs == 2419 && te - ts == 2419) {
        // fprintf(stderr, "[M::%s::mode->%ld] ch_n::%ld, q::[%ld, %ld), t::[%ld, %ld)\n", 
        //     __func__, mode, ch_n, qs, qe, ts, te);
    // }
    
    for (k = occ = m = 0; k < ch_n; k++) {
        // if(ch_n == 2 && mode == 2 && qe - qs == 2419 && te - ts == 2419) {
        // fprintf(stderr, "+i::%ld[M::%s::] x::[%u, %u), y::[%u, %u), cnt::%u\n", k, __func__, 
        //     ch_a[k].self_offset+1-(ch_a[k].cnt&((uint32_t)(0xffu))), ch_a[k].self_offset+1,
        //     ch_a[k].offset+1-(ch_a[k].cnt&((uint32_t)(0xffu))), ch_a[k].offset+1, (ch_a[k].cnt&(0xffu)));
        // }
        if(!(ch_a[k].cnt&(0xffu))) continue;
        occ++;
        if((ch_a[k].cnt&(0xffu)) > 1) occ++;
        ch_a[m++] = ch_a[k];
    }
    ch_n = m; if(!ch_n) return ch_n;
    occ += prefix + suffix;
    // if(ch_n == 2 && mode == 2 && qe - qs == 2419 && te - ts == 2419) {
        // fprintf(stderr, "+[M::%s::] occ::%ld\n", __func__, occ);
    // }

    ncn = occ + cl->length;
    if(cl->size < ncn) {
        cl->size = ncn;
        REALLOC(cl->list, cl->size);
        // cl->list = (k_mer_hit*)realloc(cl->list, (sizeof((*(cl->list)))*cl->length));
    }
    ch_a = cl->list + cl->length; assert((cl->length+occ)<= cl->size);

    k_mer_hit cht;
    ///global or backward
    if(suffix) {
        cht.self_offset = qe;
        cht.offset = te;
        cht.cnt = 1; cht.readID = 1;//make it as primary chain
        cht.strand = 0;
        ch_a[--occ] = cht;
        // fprintf(stderr, "occ::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", occ, __func__, 
        //     cht.self_offset, cht.offset, cht.cnt, cht.readID);
    }
    for (k = ch_n-1; k >= 0; k--) {
        if(!(ch_a[k].cnt&(0xffu))) continue;
        ///end
        cht.self_offset = ch_a[k].self_offset+1;
        cht.offset = ch_a[k].offset+1;
        cht.strand = 0;
        cht.cnt = cht.readID = (ch_a[k].cnt&(0xffu));
        //make it as non-primary chain
        if((ch_a[k].cnt&(0xffu)) < h_khit) cht.readID = cht.cnt + 1;
        ch_a[--occ] = cht;
        // fprintf(stderr, "occ::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", occ, __func__, 
        //     cht.self_offset, cht.offset, cht.cnt, cht.readID);

        if((ch_a[k].cnt&(0xffu)) > 1) {
            ///start
            cht.self_offset = ch_a[k].self_offset+1-(ch_a[k].cnt&(0xffu));
            cht.offset = ch_a[k].offset+1-(ch_a[k].cnt&(0xffu));
            cht.strand = 0;
            cht.cnt = cht.readID = (ch_a[k].cnt&(0xffu));
            //make it as non-primary chain
            if((ch_a[k].cnt&(0xffu)) < h_khit) cht.readID = cht.cnt + 1;
            ch_a[--occ] = cht;
            // fprintf(stderr, "occ::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", occ, __func__, 
            // cht.self_offset, cht.offset, cht.cnt, cht.readID);
        }
    }
    
    if(prefix) { ///global or forward
        cht.self_offset = qs;
        cht.offset = ts;
        cht.cnt = 1; cht.readID = 1;//make it as primary chain
        cht.strand = 0;
        ch_a[--occ] = cht;
        // fprintf(stderr, "occ::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", occ, __func__, 
        //     cht.self_offset, cht.offset, cht.cnt, cht.readID);
    }
    // if(ch_n == 2 && mode == 2 && qe - qs == 2419 && te - ts == 2419) {
        // fprintf(stderr, "-[M::%s::] occ::%ld\n", __func__, occ);
    // }
    // if(!(occ == 0)) {
    //     fprintf(stderr, "[M::%s] rid::%ld, name::%.*s\n", __func__, rid,
    //      (int32_t)UL_INF.nid.a[rid].n, UL_INF.nid.a[rid].a);
    // }
    assert(occ == 0);
    ch_n = occ = ncn - cl->length;
    uint64_t q[2], t[2]; 
    q[0] = q[1] = t[0] = t[1] = (uint64_t)-1;
    if(prefix) {
        q[0] = qs; t[0] = ts;
    }
    if(suffix) {
        q[1] = qe; t[1] = te;
    }

    // for (k = 0; k < ch_n; k++) {
    //     fprintf(stderr, "<i::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", k, __func__, 
    //         ch_a[k].self_offset, ch_a[k].offset, ch_a[k].cnt, ch_a[k].readID);
    // }
    for (k = m = occ = 0; k < ch_n; k++) {
        if((k>0) && (ch_a[k].self_offset==q[0]) && (ch_a[k].offset=t[0])) continue;
        if(((k+1)<ch_n) && (ch_a[k].self_offset==q[1]) && (ch_a[k].offset=t[1])) continue;
        if(m>0) {
            if((ch_a[k].self_offset>ch_a[m-1].self_offset) && (ch_a[k].offset>ch_a[m-1].offset)) {
                occ++;
            }
            if(ch_a[k].self_offset<=ch_a[m-1].self_offset) srt = 0;
        } else {
            occ++;
        }
        ch_a[m++] = ch_a[k];
    }
    ch_n = m;
    if(occ == ch_n) return ch_n;///already colinear
    if(!srt) {
        radix_sort_k_mer_hit_self(ch_a, ch_a + ch_n);
        for (i = 1, j = 0; i <= ch_n; i++) {
            if (i == ch_n || ch_a[i].self_offset != ch_a[j].self_offset) {
                if(i - j > 1) radix_sort_k_mer_hit_off(ch_a+j, ch_a+i);
                j = i;
            }
        }
    }

    // for (k = 0; k < ch_n; k++) {
    //     fprintf(stderr, ">i::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", k, __func__, 
    //         ch_a[k].self_offset, ch_a[k].offset, ch_a[k].cnt, ch_a[k].readID);
    // }
    occ = ch_n;
    ch_n = lchain_simple(ch_a+prefix, ch_n-prefix-suffix, ch_a+prefix, &(cl->chainDP), max_skip, max_iter);
    ch_n += prefix + suffix; if(suffix) ch_a[ch_n-1] = ch_a[occ-1];
    // for (k = 0; k < ch_n; k++) {
    //     fprintf(stderr, "-i::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", k, __func__, 
    //         ch_a[k].self_offset, ch_a[k].offset, ch_a[k].cnt, ch_a[k].readID);
    // }
    
    return ch_n;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %r9, %rbp
movq %r8, 0x8(%rsp)
movq %rcx, %rbx
movq %rdx, %r11
movq %rdi, %r12
movq 0x78(%rsp), %r10
movq 0x8(%rdi), %rax
shlq $0x4, %rax
addq (%rdi), %rax
xorl %r14d, %r14d
testq %rsi, %rsi
cmovleq %r14, %rsi
movq %rax, %rcx
xorl %r13d, %r13d
subq $0x1, %rsi
jb 0x370c6
movzbl 0xc(%rcx), %edx
testl %edx, %edx
je 0x370c0
xorl %edi, %edi
cmpl $0x1, %edx
sete %dil
subq %rdi, %r14
addq $0x2, %r14
leaq 0x1(%r13), %rdx
shlq $0x4, %r13
movdqu (%rcx), %xmm0
movdqu %xmm0, (%rax,%r13)
movq %rdx, %r13
addq $0x10, %rcx
jmp 0x3708d
xorl %ecx, %ecx
cmpq $0x2, %rbx
setb %al
testq %r13, %r13
je 0x3713e
movb %al, %cl
movq %rbx, %rax
andq $-0x3, %rax
cmpq $0x1, %rax
movq %rcx, 0x30(%rsp)
adcq $0x0, %rcx
movq %rcx, 0x28(%rsp)
addq %rcx, %r14
movq (%r12), %rdi
movq 0x8(%r12), %rdx
leaq (%rdx,%r14), %r15
movq 0x10(%r12), %rax
cmpq %r15, %rax
jge 0x37145
movq %r15, 0x10(%r12)
movq %r15, %rsi
shlq $0x4, %rsi
movq %r11, (%rsp)
callq 0x2370
movq (%rsp), %r11
movq 0x78(%rsp), %r10
movq %rax, %rdi
movq %rax, (%r12)
movq 0x8(%r12), %rdx
movq 0x10(%r12), %rax
leaq (%rdx,%r14), %rcx
jmp 0x37148
xorl %eax, %eax
jmp 0x373c9
movq %r15, %rcx
movq %r12, (%rsp)
cmpq %rax, %rcx
jg 0x3748b
shlq $0x4, %rdx
leaq (%rdi,%rdx), %r12
pushq $0x1
popq %rax
testq $-0x3, %rbx
movq %rdi, 0x18(%rsp)
movq %rdx, 0x10(%rsp)
je 0x373d8
addq %rdi, %rdx
addq $0xc, %rdx
pcmpeqd %xmm0, %xmm0
movq %r14, %rcx
movq %r13, %rsi
shlq $0x4, %rsi
addq %rdx, %rsi
movq 0x8(%rsp), %r14
testq %r13, %r13
jle 0x37209
decq %r13
movzbl -0x10(%rsi), %edi
addq $-0x10, %rsi
testq %rdi, %rdi
je 0x37194
xorl %r8d, %r8d
cmpq %r11, %rdi
setl %r8b
addl %edi, %r8d
leaq -0x1(%rcx), %r14
movq %r14, %r9
shlq $0x4, %r9
movl %r8d, (%r12,%r9)
movq -0x8(%rsi), %xmm1
psubd %xmm0, %xmm1
movq %xmm1, 0x4(%r12,%r9)
movl %edi, 0xc(%r12,%r9)
movzbl (%rsi), %edi
cmpl $0x2, %edi
jb 0x37182
movl -0x8(%rsi), %edx
movl -0x4(%rsi), %esi
subl %edi, %esi
incl %esi
subl %edi, %edx
incl %edx
xorl %r8d, %r8d
cmpq %r11, %rdi
setl %r8b
addl %edi, %r8d
addq $-0x2, %rcx
movq %rcx, %r14
jmp 0x373e5
cmpq $0x1, %rbx
ja 0x37231
decq %rcx
movq %rcx, %rdx
shlq $0x4, %rdx
movl %eax, (%r12,%rdx)
movq 0x70(%rsp), %rsi
movl %esi, 0x4(%r12,%rdx)
movl %r14d, 0x8(%r12,%rdx)
movl %eax, 0xc(%r12,%rdx)
testq %rcx, %rcx
jne 0x374aa
cmpq $0x2, %rbx
setb %al
testq $-0x3, %rbx
sete %dil
movq (%rsp), %rcx
subq 0x8(%rcx), %r15
movq 0x70(%rsp), %rcx
testl %ecx, %ecx
sete %cl
andb %al, %cl
movq %r10, %rsi
testl %r10d, %r10d
sete %dl
andb %dil, %dl
xorl %r9d, %r9d
testq %r15, %r15
movl $0x0, %edi
cmovgq %r15, %rdi
pushq $0x1
popq %rax
movq %rax, 0x20(%rsp)
xorl %eax, %eax
xorl %r13d, %r13d
cmpq %rdi, %r9
je 0x3735f
movq %r9, %r8
testq %r9, %r9
je 0x372c0
cmpq $0x1, %rbx
ja 0x372c0
movq %r8, %r9
shlq $0x4, %r9
movl 0x8(%r12,%r9), %r10d
cmpq %r14, %r10
jne 0x372c0
addq %r12, %r9
movq 0x70(%rsp), %r10
movl %r10d, 0x4(%r9)
testb %cl, %cl
je 0x37321
leaq 0x1(%r8), %r9
cmpq %r15, %r9
jge 0x372ee
testq $-0x3, %rbx
jne 0x372ee
movq %r8, %r10
shlq $0x4, %r10
movl 0x8(%r12,%r10), %r11d
cmpq %rbp, %r11
jne 0x372ee
addq %r12, %r10
movl %esi, 0x4(%r10)
testb %dl, %dl
je 0x37288
testq %r13, %r13
je 0x3732c
movq %r8, %r10
shlq $0x4, %r10
movl 0x8(%r12,%r10), %r14d
movq %r13, %r11
shlq $0x4, %r11
cmpl -0x8(%r12,%r11), %r14d
jbe 0x37331
addq %r12, %r10
addq %r12, %r11
movl -0xc(%r11), %r11d
cmpl 0x4(%r10), %r11d
adcq $0x0, %rax
jmp 0x3733a
incq %r8
movq %r8, %r9
jmp 0x37288
incq %rax
jmp 0x3733f
movq $0x0, 0x20(%rsp)
movq 0x8(%rsp), %r14
shlq $0x4, %r8
leaq 0x1(%r13), %r10
shlq $0x4, %r13
movdqu (%r12,%r8), %xmm0
movdqu %xmm0, (%r12,%r13)
movq %r10, %r13
jmp 0x37288
cmpq %r13, %rax
je 0x373c9
cmpq $0x0, 0x20(%rsp)
je 0x3740e
movq 0x30(%rsp), %rdi
shll $0x4, %edi
addq %r12, %rdi
movq %r13, %rsi
movq 0x28(%rsp), %r14
subq %r14, %rsi
movq (%rsp), %rcx
addq $0x18, %rcx
movq %rdi, %rdx
movq 0x80(%rsp), %r8
movq 0x88(%rsp), %r9
callq 0x1782d
addq %r14, %rax
testq $-0x3, %rbx
jne 0x373c9
shlq $0x4, %r13
movq %rax, %rcx
shlq $0x4, %rcx
movups -0x10(%r12,%r13), %xmm0
movups %xmm0, -0x10(%r12,%rcx)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
decq %r14
movl %eax, %r8d
movl %r10d, %edx
movl %ebp, %esi
movl %eax, %edi
movq %r14, %rcx
shlq $0x4, %rcx
movl %r8d, (%r12,%rcx)
movl %edx, 0x4(%r12,%rcx)
movl %esi, 0x8(%r12,%rcx)
movl %edi, 0xc(%r12,%rcx)
movq 0x18(%rsp), %rdi
movq 0x10(%rsp), %rdx
jmp 0x37177
movq %r13, %rsi
shlq $0x4, %rsi
addq %r12, %rsi
movq %r12, %rdi
callq 0x1a2b0
movq 0x18(%rsp), %rax
movq 0x10(%rsp), %rcx
leaq (%rcx,%rax), %r14
addq $0x10, %r14
pushq $0x1
popq %r15
xorl %edi, %edi
movq %r13, %rbp
subq $0x1, %rbp
jb 0x37370
je 0x3745e
movl 0x8(%r14), %eax
movq %rdi, %rcx
shlq $0x4, %rcx
cmpl 0x8(%r12,%rcx), %eax
jne 0x3745e
movq %rdi, %rax
jmp 0x3747f
movq %r15, %rcx
subq %rdi, %rcx
movq %r15, %rax
cmpq $0x2, %rcx
jl 0x3747f
shlq $0x4, %rdi
addq %r12, %rdi
movq %r14, %rsi
callq 0x1a502
movq %r15, %rax
incq %r15
addq $0x10, %r14
movq %rax, %rdi
jmp 0x3743b
leaq 0x1adc88(%rip), %rdi    # 0x1e511a
leaq 0x1ac20a(%rip), %rsi    # 0x1e36a3
leaq 0x1adc96(%rip), %rcx    # 0x1e5136
movl $0x4204, %edx           # imm = 0x4204
callq 0x2110
leaq 0x1add0a(%rip), %rdi    # 0x1e51bb
leaq 0x1ac1eb(%rip), %rsi    # 0x1e36a3
leaq 0x1adc77(%rip), %rcx    # 0x1e5136
movl $0x423c, %edx           # imm = 0x423C
callq 0x2110