// File: /workspace/github_cpp_makefile_star2_O3/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 %r8, 0x10(%rsp)
movq %rcx, %rbx
movq %rdx, %r15
xorl %r13d, %r13d
testq $-0x3, %rcx
sete %cl
xorl %r10d, %r10d
cmpq $0x2, %rbx
setb %dl
testq %rsi, %rsi
jle 0x68709
movq %r9, 0x8(%rsp)
movq 0x8(%rdi), %rax
shlq $0x4, %rax
addq (%rdi), %rax
movb %cl, %r13b
movb %dl, %r10b
xorl %r12d, %r12d
movq %rax, %rcx
xorl %r14d, %r14d
movzbl 0xc(%rcx), %edx
testl %edx, %edx
je 0x6843d
xorl %r8d, %r8d
cmpl $0x1, %edx
sete %r8b
subq %r8, %r14
addq $0x2, %r14
leaq 0x1(%r12), %rdx
shlq $0x4, %r12
movdqu (%rcx), %xmm0
movdqu %xmm0, (%rax,%r12)
movq %rdx, %r12
addq $0x10, %rcx
decq %rsi
jne 0x6840e
testq %r12, %r12
je 0x68709
movq %r10, 0x28(%rsp)
addq %r10, %r13
addq %r13, %r14
movq (%rdi), %rax
movq 0x8(%rdi), %rsi
leaq (%rsi,%r14), %rbp
movq 0x10(%rdi), %rdx
cmpq %rbp, %rdx
movq %rdi, (%rsp)
jge 0x6849a
movq %rbp, 0x10(%rdi)
movq %rbp, %rsi
shlq $0x4, %rsi
movq %rax, %rdi
callq 0x2370
movq (%rsp), %rdi
movq %rax, (%rdi)
movq 0x8(%rdi), %rsi
movq 0x10(%rdi), %rdx
leaq (%rsi,%r14), %rcx
jmp 0x6849d
movq %rbp, %rcx
movq %r13, 0x30(%rsp)
cmpq %rdx, %rcx
jg 0x68821
shlq $0x4, %rsi
leaq (%rax,%rsi), %r13
testq $-0x3, %rbx
movq %rax, 0x20(%rsp)
jne 0x684ee
decq %r14
movq %r14, %rax
shlq $0x4, %rax
movl $0x1, %ecx
movl %ecx, (%r13,%rax)
movq 0x78(%rsp), %rdx
movl %edx, 0x4(%r13,%rax)
movq 0x8(%rsp), %rdx
movl %edx, 0x8(%r13,%rax)
movl %ecx, 0xc(%r13,%rax)
movq %rsi, 0x18(%rsp)
testq %r12, %r12
jle 0x685ad
leaq 0x1(%r12), %rax
shlq $0x4, %r12
leaq (%r12,%r13), %rcx
addq $-0x4, %rcx
pcmpeqd %xmm0, %xmm0
movq 0x8(%rsp), %r12
movzbl (%rcx), %esi
testq %rsi, %rsi
je 0x68594
xorl %r9d, %r9d
cmpq %r15, %rsi
setl %r9b
addl %esi, %r9d
leaq -0x1(%r14), %rdx
movq %rdx, %r8
shlq $0x4, %r8
movl %r9d, (%r13,%r8)
movq -0x8(%rcx), %xmm1
psubd %xmm0, %xmm1
movq %xmm1, 0x4(%r13,%r8)
movl %esi, 0xc(%r13,%r8)
movzbl (%rcx), %esi
cmpl $0x2, %esi
jb 0x68597
xorl %edx, %edx
cmpq %r15, %rsi
setl %dl
addl %esi, %edx
addq $-0x2, %r14
movq %r14, %r8
shlq $0x4, %r8
movl %edx, (%r13,%r8)
movq -0x8(%rcx), %xmm1
movd %esi, %xmm2
pshufd $0x50, %xmm2, %xmm2     # xmm2 = xmm2[0,0,1,1]
psubd %xmm2, %xmm1
psubd %xmm0, %xmm1
movq %xmm1, 0x4(%r13,%r8)
movl %esi, 0xc(%r13,%r8)
movq %r14, %rdx
decq %rax
addq $-0x10, %rcx
movq %rdx, %r14
cmpq $0x1, %rax
ja 0x68516
jmp 0x685b5
movq %r14, %rdx
movq 0x8(%rsp), %r12
cmpq $0x1, %rbx
ja 0x685ea
decq %rdx
movq %rdx, %rax
shlq $0x4, %rax
movl $0x1, %ecx
movl %ecx, (%r13,%rax)
movq 0x70(%rsp), %rsi
movl %esi, 0x4(%r13,%rax)
movq 0x10(%rsp), %r15
movl %r15d, 0x8(%r13,%rax)
movl %ecx, 0xc(%r13,%rax)
jmp 0x685ef
movq 0x10(%rsp), %r15
testq %rdx, %rdx
jne 0x68840
subq 0x8(%rdi), %rbp
jle 0x68709
cmpq $0x2, %rbx
setb %al
testq $-0x3, %rbx
sete %sil
movq 0x70(%rsp), %rcx
testl %ecx, %ecx
sete %cl
andb %al, %cl
movq 0x78(%rsp), %rax
testl %eax, %eax
sete %dl
andb %sil, %dl
movl $0x1, %esi
xorl %r14d, %r14d
xorl %eax, %eax
xorl %edi, %edi
testq %rdi, %rdi
je 0x68669
cmpq $0x1, %rbx
ja 0x68669
movq %rdi, %r8
shlq $0x4, %r8
movl 0x8(%r13,%r8), %r9d
cmpq %r15, %r9
jne 0x68669
addq %r13, %r8
movq 0x70(%rsp), %r9
movl %r9d, 0x4(%r8)
testb %cl, %cl
je 0x68701
leaq 0x1(%rdi), %r8
cmpq %rbp, %r8
jge 0x6869c
testq $-0x3, %rbx
jne 0x6869c
movq %rdi, %r9
shlq $0x4, %r9
movl 0x8(%r13,%r9), %r10d
cmpq %r12, %r10
jne 0x6869c
addq %r13, %r9
movq 0x78(%rsp), %r10
movl %r10d, 0x4(%r9)
testb %dl, %dl
je 0x686f3
testq %r14, %r14
jle 0x686cf
movq %rdi, %r9
shlq $0x4, %r9
movl 0x8(%r13,%r9), %r11d
movq %r14, %r10
shlq $0x4, %r10
cmpl -0x8(%r13,%r10), %r11d
jbe 0x686d4
addq %r13, %r9
addq %r13, %r10
movl -0xc(%r10), %r10d
cmpl 0x4(%r9), %r10d
adcq $0x0, %rax
jmp 0x686d6
incq %rax
jmp 0x686d6
xorl %esi, %esi
shlq $0x4, %rdi
leaq 0x1(%r14), %r9
shlq $0x4, %r14
movdqu (%r13,%rdi), %xmm0
movdqu %xmm0, (%r13,%r14)
movq %r9, %r14
movq %r8, %rdi
cmpq %rbp, %r8
jl 0x68639
jmp 0x6871a
incq %rdi
movq %rdi, %r8
jmp 0x686f3
xorl %eax, %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpq %r14, %rax
je 0x6870b
testq %rsi, %rsi
movq (%rsp), %rcx
jne 0x687c1
movq %r14, %rsi
shlq $0x4, %rsi
addq %r13, %rsi
movq %r13, %rdi
callq 0x46635
movq (%rsp), %rcx
testq %r14, %r14
jle 0x687c1
movq %r14, %r12
negq %r12
movq 0x20(%rsp), %rax
movq 0x18(%rsp), %rdx
leaq (%rdx,%rax), %r15
addq $0x10, %r15
movl $0x1, %ebp
xorl %edi, %edi
movq %r12, %rax
addq %rbp, %rax
je 0x68785
movl 0x8(%r15), %eax
movq %rdi, %rdx
shlq $0x4, %rdx
cmpl 0x8(%r13,%rdx), %eax
jne 0x68785
movq %rdi, %rax
jmp 0x687aa
movq %rbp, %rdx
subq %rdi, %rdx
movq %rbp, %rax
cmpq $0x2, %rdx
jl 0x687aa
shlq $0x4, %rdi
addq %r13, %rdi
movq %r15, %rsi
callq 0x4687d
movq (%rsp), %rcx
movq %rbp, %rax
leaq (%r12,%rbp), %rdx
incq %rdx
incq %rbp
addq $0x10, %r15
movq %rax, %rdi
cmpq $0x1, %rdx
jne 0x68766
movq 0x28(%rsp), %rdi
shll $0x4, %edi
addq %r13, %rdi
movq %r14, %rsi
movq 0x30(%rsp), %r15
subq %r15, %rsi
addq $0x18, %rcx
movq %rdi, %rdx
movq 0x80(%rsp), %r8
movq 0x88(%rsp), %r9
callq 0x43c57
addq %r15, %rax
testq $-0x3, %rbx
jne 0x6870b
shlq $0x4, %r14
movq %rax, %rcx
shlq $0x4, %rcx
movdqu -0x10(%r13,%r14), %xmm0
movdqu %xmm0, -0x10(%r13,%rcx)
jmp 0x6870b
leaq 0x1ca9a2(%rip), %rdi    # 0x2331ca
leaq 0x1c8f24(%rip), %rsi    # 0x231753
leaq 0x1ca9b0(%rip), %rcx    # 0x2331e6
movl $0x4204, %edx           # imm = 0x4204
callq 0x2110
leaq 0x1caa24(%rip), %rdi    # 0x23326b
leaq 0x1c8f05(%rip), %rsi    # 0x231753
leaq 0x1ca991(%rip), %rcx    # 0x2331e6
movl $0x423c, %edx           # imm = 0x423C
callq 0x2110