// File: chhylp123[P]hifiasm/Overlaps.cpp
// Function: unroll_tangle(ma_ug_t*, ma_ug_t*, unsigned long*, unsigned long, unsigned int, unsigned int, kvec_t_u64_warp*, unsigned int, buf_t*, unsigned char*, float)
void unroll_tangle(ma_ug_t *ug, ma_ug_t *length_ug, uint64_t* nodes, uint64_t nodes_n, 
uint32_t beg, uint32_t end, kvec_t_u64_warp* edges, uint32_t trio_flag, buf_t* bb, uint8_t* visit,
float drop_ratio)
{
    uint32_t v, w, is_found = 0, convex, i, beg_c, end_c;
    long long tmp, max_stop_nodeLen, max_stop_baseLen, begLen, endLen, missLen;
    long long totalNodeLen = 0, totalBaseLen = 0;
    asg_t* nsg = ug->g;
    edges->a.n = 0;
    save_all_edges(edges, nsg, nodes, nodes_n, beg, end, &beg_c, &end_c);


    for (i = 0; i < nodes_n; i++)
    {
        v = (uint32_t)nodes[i];
        totalNodeLen += ug->u.a[v].n;
        totalBaseLen += ug->g->seq[v].len;
    }
    totalNodeLen += ug->u.a[beg>>1].n + ug->u.a[end>>1].n + 1;
    totalBaseLen += ug->g->seq[beg>>1].len + ug->g->seq[end>>1].len + 1;
    ///each might be visited twice
    totalNodeLen = totalNodeLen * 2;
    totalBaseLen = totalBaseLen * 2;

    /**************************debug**************************/
    // uint32_t debug_is_access = 0, debug_is_circle = 0;
    // check_connective(nsg, beg, end, totalNodeLen, bb, visit, ug, nodes, nodes_n, &debug_is_access, 
    // &debug_is_circle);
    // if(debug_is_access==0) fprintf(stderr, "Cannot approch end: beg: %u, end: %u\n", beg>>1, end>>1);
    // if(debug_is_circle==0) fprintf(stderr, "Not circle: beg: %u, end: %u\n", beg>>1, end>>1);
    // if(debug_is_circle==1) fprintf(stderr, "Circle: beg: %u, end: %u\n", beg>>1, end>>1);
    /**************************debug**************************/
    is_found = process_tangles(ug, nodes, nodes_n, beg, end, bb, visit, trio_flag, totalNodeLen, 
    totalBaseLen);
    ///if(is_found == 1) fprintf(stderr, "***Found: beg>>1: %u, end>>1: %u\n", beg>>1, end>>1);

    if(is_found == 0)
    {
        is_found = cut_edges_progressive(ug, edges, drop_ratio, nodes, nodes_n, 
        beg, end, bb, visit, trio_flag, totalNodeLen, totalBaseLen, 48);

        ///if(is_found == 1) fprintf(stderr, "***Cutting Found: beg>>1: %u, end>>1: %u\n", beg>>1, end>>1);
    }

    if(is_found == 1)
    {
        get_unitig(length_ug->g, length_ug, beg^1, &convex, &begLen, &tmp, &max_stop_nodeLen, 
                        &max_stop_baseLen, 1, NULL);

        get_unitig(length_ug->g, length_ug, end, &convex, &endLen, &tmp, &max_stop_nodeLen, 
                        &max_stop_baseLen, 1, NULL);


        missLen = 0;
        for (i = 0; i < nodes_n; i++)
        {
            v = (uint32_t)nodes[i];
            if(nsg->seq[v].del || nsg->seq[v].c == ALTER_LABLE)
            {
                missLen += ug->u.a[v].n;
            }
        }
        ///resolved!
        if(missLen <= (begLen+endLen)*TANGLE_MISSED_THRES)
        {
            is_found = 0;
            w = beg^1;
            is_found = find_spec_node(nsg, beg, end, &w, 1, totalNodeLen, bb, visit, ug);
        }
        else
        {
            is_found = 0;
        }        
    }

    recover_edges(nsg, edges, nodes, nodes_n, beg, end, beg_c, end_c, 1-is_found);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
subq $0xc0, %rsp
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movl 0x18(%rbp), %eax
movq 0x10(%rbp), %rax
movq %rdi, -0x18(%rbp)
movq %rsi, -0x20(%rbp)
movq %rdx, -0x28(%rbp)
movq %rcx, -0x30(%rbp)
movl %r8d, -0x34(%rbp)
movl %r9d, -0x38(%rbp)
movss %xmm0, -0x3c(%rbp)
movl $0x0, -0x48(%rbp)
movq $0x0, -0x90(%rbp)
movq $0x0, -0x98(%rbp)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0xa0(%rbp)
movq 0x10(%rbp), %rax
movq $0x0, (%rax)
movq 0x10(%rbp), %rdi
movq -0xa0(%rbp), %rsi
movq -0x28(%rbp), %rdx
movq -0x30(%rbp), %rcx
movl -0x34(%rbp), %r8d
movl -0x38(%rbp), %r9d
leaq -0x54(%rbp), %r10
leaq -0x58(%rbp), %rax
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x146f30
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpq -0x30(%rbp), %rax
jae 0x149085
movq -0x28(%rbp), %rax
movl -0x50(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movl %eax, -0x40(%rbp)
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x40(%rbp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl 0x10(%rax), %eax
addq -0x90(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rax
movl -0x40(%rbp), %ecx
movl (%rax,%rcx,8), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movl %eax, %eax
addq -0x98(%rbp), %rax
movq %rax, -0x98(%rbp)
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x149019
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x34(%rbp), %ecx
shrl %ecx
movl %ecx, %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl 0x10(%rax), %eax
movq -0x18(%rbp), %rcx
movq 0x10(%rcx), %rcx
movl -0x38(%rbp), %edx
shrl %edx
movl %edx, %edx
imulq $0x28, %rdx, %rdx
addq %rdx, %rcx
addl 0x10(%rcx), %eax
addl $0x1, %eax
movl %eax, %eax
addq -0x90(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rax
movl -0x34(%rbp), %ecx
shrl %ecx
movl %ecx, %ecx
movl (%rax,%rcx,8), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movq -0x18(%rbp), %rcx
movq 0x18(%rcx), %rcx
movq 0x20(%rcx), %rcx
movl -0x38(%rbp), %edx
shrl %edx
movl %edx, %edx
movl (%rcx,%rdx,8), %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
addl %ecx, %eax
addl $0x1, %eax
cltq
addq -0x98(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x90(%rbp), %rax
shlq %rax
movq %rax, -0x90(%rbp)
movq -0x98(%rbp), %rax
shlq %rax
movq %rax, -0x98(%rbp)
movq -0x18(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x30(%rbp), %rdx
movl -0x34(%rbp), %ecx
movl -0x38(%rbp), %r8d
movq 0x20(%rbp), %r9
movq 0x28(%rbp), %rbx
movl 0x18(%rbp), %r11d
movq -0x90(%rbp), %r10
movq -0x98(%rbp), %rax
movq %rbx, (%rsp)
movl %r11d, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq %rax, 0x18(%rsp)
callq 0x168be0
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x48(%rbp)
jne 0x1491e5
movq -0x18(%rbp), %rdi
movq 0x10(%rbp), %rsi
movss -0x3c(%rbp), %xmm0
movq -0x28(%rbp), %rdx
movq -0x30(%rbp), %rcx
movl -0x34(%rbp), %r8d
movl -0x38(%rbp), %r9d
movq 0x20(%rbp), %r14
movq 0x28(%rbp), %rbx
movl 0x18(%rbp), %r11d
movq -0x90(%rbp), %r10
movq -0x98(%rbp), %rax
movq %r14, (%rsp)
movq %rbx, 0x8(%rsp)
movl %r11d, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movq %rax, 0x20(%rsp)
movl $0x30, 0x28(%rsp)
callq 0x148bf0
movl %eax, -0x48(%rbp)
cmpl $0x1, -0x48(%rbp)
jne 0x149389
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x20(%rbp), %rsi
movl -0x34(%rbp), %edx
xorl $0x1, %edx
leaq -0x4c(%rbp), %rcx
leaq -0x78(%rbp), %r8
leaq -0x60(%rbp), %r9
leaq -0x68(%rbp), %r10
leaq -0x70(%rbp), %rax
xorl %r11d, %r11d
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movl $0x1, 0x10(%rsp)
movq $0x0, 0x18(%rsp)
callq 0x166c30
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x20(%rbp), %rsi
movl -0x38(%rbp), %edx
leaq -0x4c(%rbp), %rcx
leaq -0x80(%rbp), %r8
leaq -0x60(%rbp), %r9
leaq -0x68(%rbp), %r10
leaq -0x70(%rbp), %rax
xorl %r11d, %r11d
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
movl $0x1, 0x10(%rsp)
movq $0x0, 0x18(%rsp)
callq 0x166c30
movq $0x0, -0x88(%rbp)
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpq -0x30(%rbp), %rax
jae 0x149306
movq -0x28(%rbp), %rax
movl -0x50(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movl %eax, -0x40(%rbp)
movq -0xa0(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x40(%rbp), %ecx
movl (%rax,%rcx,8), %eax
shrl $0x1f, %eax
cmpl $0x0, %eax
jne 0x1492d6
movq -0xa0(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x40(%rbp), %ecx
movzbl 0x4(%rax,%rcx,8), %eax
cmpl $0x1, %eax
jne 0x1492f9
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x40(%rbp), %ecx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl 0x10(%rax), %eax
addq -0x88(%rbp), %rax
movq %rax, -0x88(%rbp)
jmp 0x1492fb
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x14928e
cvtsi2sdq -0x88(%rbp), %xmm1
movq -0x78(%rbp), %rax
addq -0x80(%rbp), %rax
cvtsi2sd %rax, %xmm0
movsd 0x238eec(%rip), %xmm2   # 0x382210
mulsd %xmm2, %xmm0
ucomisd %xmm1, %xmm0
jb 0x149380
movl $0x0, -0x48(%rbp)
movl -0x34(%rbp), %eax
xorl $0x1, %eax
movl %eax, -0x44(%rbp)
movq -0xa0(%rbp), %rdi
movl -0x34(%rbp), %esi
movl -0x38(%rbp), %edx
movq -0x90(%rbp), %r9
movq 0x20(%rbp), %r11
movq 0x28(%rbp), %r10
movq -0x18(%rbp), %rax
leaq -0x44(%rbp), %rcx
movl $0x1, %r8d
movq %r11, (%rsp)
movq %r10, 0x8(%rsp)
movq %rax, 0x10(%rsp)
callq 0x147c90
movl %eax, -0x48(%rbp)
jmp 0x149387
movl $0x0, -0x48(%rbp)
jmp 0x149389
movq -0xa0(%rbp), %rdi
movq 0x10(%rbp), %rsi
movq -0x28(%rbp), %rdx
movq -0x30(%rbp), %rcx
movl -0x34(%rbp), %r8d
movl -0x38(%rbp), %r9d
movl -0x54(%rbp), %r11d
movl -0x58(%rbp), %r10d
movl $0x1, %eax
subl -0x48(%rbp), %eax
movl %r11d, (%rsp)
movl %r10d, 0x8(%rsp)
movl %eax, 0x10(%rsp)
callq 0x146dd0
addq $0xc0, %rsp
popq %rbx
popq %r14
popq %rbp
retq
nopw %cs:(%rax,%rax)