// File: chhylp123[P]hifiasm/Overlaps.cpp
// Function: gen_telo_end_t(All_reads*, char const*, long, long, long, unsigned long)
telo_end_t* gen_telo_end_t(All_reads *in, const char* motif, int64_t min_sc, int64_t penalty, int64_t max_drop, uint64_t n_thread)
{
    uint64_t j, k, c, x; int absent;
    telo_end_t* p = NULL; CALLOC(p, 1);
    p->tlen = strlen(motif); p->mask = ((1ULL)<<(p->tlen<<1))-1;

    for (j = 0, p->tm = 0; j < p->tlen; ++j) {
        c = seq_nt6_table[(uint8_t)motif[j]];
        assert(c >= 0 && c <= 3);
        p->tm = (p->tm<<2)|(c);
    }
    p->n = in->total_reads; CALLOC(p->hh, p->n);

    telo_end_pip_t *aux; CALLOC(aux, 1); 
    aux->min_sc = min_sc; aux->max_drop = max_drop;
    aux->penalty = penalty; if(aux->penalty < 0) aux->penalty = (aux->penalty)*-1;
    aux->Rinf = in; aux->u = p; CALLOC(aux->aux, n_thread); 
    for (k = 0; k < n_thread; k++) init_UC_Read(&(aux->aux[k]));
    aux->h = kh_init(64); kh_resize(64, aux->h, (p->tlen*2)); // hash table for all roations of the telomere motif
    for (k = 0, x = p->tm; k < p->tlen; k++) {
        kh_put(64, aux->h, x, &absent);
        x = (((x>>((p->tlen-1)<<1))&(3ULL))|(x<<2))&p->mask;
    }
    assert(x == p->tm);
    
    kt_for(n_thread, mark_telo_ends, aux, p->n);

    for (k = 0; k < n_thread; k++) destory_UC_Read(&(aux->aux[k]));
    free(aux->aux); kh_destroy(64, aux->h); free(aux);

    uint64_t t3, t5;
    for (k = t3 = t5 = 0; k < p->n; k++) {
        if(p->hh[k]&1) {
            // fprintf(stderr, "%.*s(+)\n", (int)Get_NAME_LENGTH((*in), k), Get_NAME((*in), k));
            t5++;
        }
        if(p->hh[k]&2) {
            // fprintf(stderr, "%.*s(-)\n", (int)Get_NAME_LENGTH((*in), k), Get_NAME((*in), k));
            t3++;
        }
    }
    

    fprintf(stderr, "[M::%s::] ==> # 5'-telomeres::%lu, # 3'-telomeres::%lu, # tot::%lu, motif::%s, motif_len::%lu\n", __func__, t5, t3, p->n, motif, p->tlen);
    // exit(1);

    return p;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq $0x0, -0x60(%rbp)
movl $0x1, %edi
movl $0x28, %esi
callq 0x2140
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rdi
callq 0x20a0
movq %rax, %rcx
movq -0x60(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x60(%rbp), %rax
movq 0x18(%rax), %rcx
shlq %rcx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
subq $0x1, %rcx
movq -0x60(%rbp), %rax
movq %rcx, 0x8(%rax)
movq $0x0, -0x38(%rbp)
movq -0x60(%rbp), %rax
movq $0x0, 0x20(%rax)
movq -0x38(%rbp), %rax
movq -0x60(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jae 0xcb831
movq -0x10(%rbp), %rax
movq -0x38(%rbp), %rcx
movzbl (%rax,%rcx), %eax
movl %eax, %ecx
leaq 0x2f8e91(%rip), %rax    # 0x3c4650
movzbl (%rax,%rcx), %eax
movq %rax, -0x48(%rbp)
xorl %eax, %eax
cmpq $0x0, -0x48(%rbp)
movb %al, -0x79(%rbp)
jb 0xcb7de
cmpq $0x3, -0x48(%rbp)
setbe %al
movb %al, -0x79(%rbp)
movb -0x79(%rbp), %al
testb $0x1, %al
jne 0xcb7e7
jmp 0xcb7e9
jmp 0xcb808
leaq 0x2bb0bc(%rip), %rdi    # 0x3868ac
leaq 0x2bb0c6(%rip), %rsi    # 0x3868bd
movl $0x134, %edx            # imm = 0x134
leaq 0x2bb0c7(%rip), %rcx    # 0x3868ca
callq 0x2130
movq -0x60(%rbp), %rax
movq 0x20(%rax), %rcx
shlq $0x2, %rcx
orq -0x48(%rbp), %rcx
movq -0x60(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0xcb798
movq -0x8(%rbp), %rax
movq 0x50(%rax), %rcx
movq -0x60(%rbp), %rax
movq %rcx, (%rax)
movq -0x60(%rbp), %rax
movq (%rax), %rdi
movl $0x1, %esi
callq 0x2140
movq %rax, %rcx
movq -0x60(%rbp), %rax
movq %rcx, 0x10(%rax)
movl $0x1, %edi
movl $0x38, %esi
callq 0x2140
movq %rax, -0x68(%rbp)
movq -0x18(%rbp), %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x28(%rbp), %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x20(%rbp), %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x68(%rbp), %rax
cmpq $0x0, 0x28(%rax)
jge 0xcb8af
movq -0x68(%rbp), %rax
imulq $-0x1, 0x28(%rax), %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x8(%rbp), %rcx
movq -0x68(%rbp), %rax
movq %rcx, (%rax)
movq -0x60(%rbp), %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x30(%rbp), %rdi
movl $0x20, %esi
callq 0x2140
movq %rax, %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x8(%rax)
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x30(%rbp), %rax
jae 0xcb917
movq -0x68(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x40(%rbp), %rax
shlq $0x5, %rax
addq %rax, %rdi
callq 0x9850
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0xcb8e7
callq 0xcbb30
movq %rax, %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x18(%rax)
movq -0x68(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x60(%rbp), %rax
movq 0x18(%rax), %rax
shlq %rax
movl %eax, %esi
callq 0xcbb40
movq $0x0, -0x40(%rbp)
movq -0x60(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x40(%rbp), %rax
movq -0x60(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jae 0xcb9b7
movq -0x68(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x50(%rbp), %rsi
leaq -0x54(%rbp), %rdx
callq 0xcbf70
movq -0x50(%rbp), %rax
movq -0x60(%rbp), %rcx
movq 0x18(%rcx), %rcx
subq $0x1, %rcx
shlq %rcx
shrq %cl, %rax
andq $0x3, %rax
movq -0x50(%rbp), %rcx
shlq $0x2, %rcx
orq %rcx, %rax
movq -0x60(%rbp), %rcx
andq 0x8(%rcx), %rax
movq %rax, -0x50(%rbp)
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0xcb955
movq -0x50(%rbp), %rax
movq -0x60(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jne 0xcb9c7
jmp 0xcb9e6
leaq 0x2baf57(%rip), %rdi    # 0x386925
leaq 0x2baee8(%rip), %rsi    # 0x3868bd
movl $0x143, %edx            # imm = 0x143
leaq 0x2baee9(%rip), %rcx    # 0x3868ca
callq 0x2130
movq -0x30(%rbp), %rax
movl %eax, %edi
movq -0x68(%rbp), %rdx
movq -0x60(%rbp), %rax
movq (%rax), %rcx
leaq 0x8e2(%rip), %rsi       # 0xcc2e0
callq 0x16d710
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x30(%rbp), %rax
jae 0xcba3b
movq -0x68(%rbp), %rax
movq 0x8(%rax), %rdi
movq -0x40(%rbp), %rax
shlq $0x5, %rax
addq %rax, %rdi
callq 0x9670
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0xcba0b
movq -0x68(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x2210
movq -0x68(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0xcccb0
movq -0x68(%rbp), %rdi
callq 0x2210
movq $0x0, -0x78(%rbp)
movq $0x0, -0x70(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq -0x60(%rbp), %rcx
cmpq (%rcx), %rax
jae 0xcbadb
movq -0x60(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x40(%rbp), %rcx
movzbl (%rax,%rcx), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0xcbaa7
movq -0x78(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x78(%rbp)
movq -0x60(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x40(%rbp), %rcx
movzbl (%rax,%rcx), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0xcbacb
movq -0x70(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x70(%rbp)
jmp 0xcbacd
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0xcba76
movq 0x2f84fe(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movq -0x78(%rbp), %rcx
movq -0x70(%rbp), %r8
movq -0x60(%rbp), %rax
movq (%rax), %r9
movq -0x10(%rbp), %r10
movq -0x60(%rbp), %rax
movq 0x18(%rax), %rax
leaq 0x2bae29(%rip), %rsi    # 0x386930
leaq 0x2bae81(%rip), %rdx    # 0x38698f
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movb $0x0, %al
callq 0x22a0
movq -0x60(%rbp), %rax
addq $0x90, %rsp
popq %rbp
retq
nopl (%rax,%rax)