// File: chhylp123[P]hifiasm/gfa_ut.cpp
// Function: u2g_hybrid_detan_iter(ul_resolve_t*, usg_t*, unsigned int, unsigned int, asg64_v*, asg64_v*)
void u2g_hybrid_detan_iter(ul_resolve_t *uidx, usg_t *ng, uint32_t max_ext, uint32_t clean_round, asg64_v *in, asg64_v *ib)
{
    uint32_t n_vtx = ng->n<<1, ncut = 0, k;
    uint8_t *ff; CALLOC(ff, n_vtx);
    uint32_t *ng_occ; CALLOC(ng_occ, n_vtx); 
    uint64_t *i_idx; CALLOC(i_idx, n_vtx);
    asg64_v b64, ub64; kv_init(b64); kv_init(ub64); 
    asg64_v tx = {0,0,0}, tb = {0,0,0}, *ob = NULL, *ub = NULL;
    ob = (in?(in):(&tx)); ub = (ib?(ib):(&tb)); ob->n = ub->n = 0;
    // fprintf(stderr, "\n[M::%s::] asm_opt.is_low_het_ul::%u, max_ext::%u\n", 
    //     __func__, asm_opt.is_low_het_ul, max_ext);
    // prt_usg_t(uidx, ng, "ng0");
    for (k = 0; k < clean_round; k++) {
        ncut += ug_ext_strict(ob, ub, uidx, ng, max_ext, &ff, &ng_occ, &i_idx, &b64, &ub64);
        // if(asm_opt.is_low_het_ul) break;
        ncut += ug_ext_free(ob, ub, uidx, ng, max_ext, &ff, &ng_occ, &i_idx, &b64, &ub64, 48, 1);
        // prt_usg_t(uidx, ng, "ng_python");
        ncut += ug_ext_free(ob, ub, uidx, ng, max_ext, &ff, &ng_occ, &i_idx, &b64, &ub64, 16, 1);

        ncut += ug_ext_free(ob, ub, uidx, ng, max_ext, &ff, &ng_occ, &i_idx, &b64, &ub64, 0, 0);
        ///renew bubble for ug_ext_strict
        n_vtx = ng->n<<1; 
        REALLOC(ff, n_vtx); REALLOC(ng_occ, n_vtx); REALLOC(i_idx, n_vtx);
        renew_usg_t_bub(uidx, ng, ng_occ, ff, 0);
    }
    // // ug_ext_strict(ob, ub, uidx, ng, max_ext, &ff, &ng_occ, &i_idx, &b64, &ub64);
    // ncut += ug_ext_free(ob, ub, uidx, ng, max_ext, &ff, &ng_occ, &i_idx, &b64, &ub64, 50);
    // prt_usg_t(uidx, ng, "ng.db");
    // ncut += ug_ext_free(ob, ub, uidx, ng, max_ext, &ff, &ng_occ, &i_idx, &b64, &ub64, 10);
    // ncut += ug_ext_strict(ob, ub, uidx, ng, max_ext, &ff, &ng_occ, &i_idx, &b64, &ub64);
    // prt_usg_t(uidx, ng, "ng.db");
    if(ncut) {
        usg_cleanup(ng); 
        // if((max_ext>>1) > 0) usg_arc_cut_tips(ng, (max_ext>>1), 1, ub);
        usg_arc_cut_tips(ng, max_ext, 1, ub);

        // if(ng->n > 139131) {
        //     fprintf(stderr, ">[M::%s::] ng->a[139131].del::%u\n", __func__, 
        //     ng->a[139131].del);
        // }
    }
    // prt_usg_t(uidx, ng, "ng2");
    // u2g_hybrid_aln(uidx, ng, ob, ub);
    // if(ug_ext(uidx, ng, ub->a, ub->n, ob->a, max_ext, ff, ng_occ, i_idx, &b64, &ub64)) {
    //     // debug_sysm_usg_t(ng, __func__);
    //     usg_cleanup(ng);
    //     // debug_sysm_usg_t(ng, __func__);
    // }
    
    // prt_usg_t(uidx, ng, "ng0");
    // if(ug_ext_free(ob, ub, uidx, ng, max_ext, &ff, &ng_occ, &i_idx, &b64, &ub64, 50)) {
    //     usg_cleanup(ng);
    // }
    // prt_usg_t(uidx, ng, "ng1");
    
    if(!in) free(tx.a); if(!ib) free(tb.a);
    free(ng_occ); free(i_idx); free(ff); kv_destroy(b64); kv_destroy(ub64); 
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
subq $0x100, %rsp            # imm = 0x100
movq %rdi, -0x18(%rbp)
movq %rsi, -0x20(%rbp)
movl %edx, -0x24(%rbp)
movl %ecx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
shlq %rax
movl %eax, -0x3c(%rbp)
movl $0x0, -0x40(%rbp)
movl -0x3c(%rbp), %eax
movl %eax, %edi
movl $0x1, %esi
callq 0x2140
movq %rax, -0x50(%rbp)
movl -0x3c(%rbp), %eax
movl %eax, %edi
movl $0x4, %esi
callq 0x2140
movq %rax, -0x58(%rbp)
movl -0x3c(%rbp), %eax
movl %eax, %edi
movl $0x8, %esi
callq 0x2140
movq %rax, -0x60(%rbp)
movq $0x0, -0x70(%rbp)
movq $0x0, -0x78(%rbp)
movq $0x0, -0x68(%rbp)
movq $0x0, -0x88(%rbp)
movq $0x0, -0x90(%rbp)
movq $0x0, -0x80(%rbp)
leaq -0xa8(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x2100
leaq -0xc0(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x2100
movq $0x0, -0xc8(%rbp)
movq $0x0, -0xd0(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x36b908
movq -0x30(%rbp), %rax
movq %rax, -0xd8(%rbp)
jmp 0x36b918
leaq -0xa8(%rbp), %rax
movq %rax, -0xd8(%rbp)
jmp 0x36b918
movq -0xd8(%rbp), %rax
movq %rax, -0xc8(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x36b93a
movq -0x38(%rbp), %rax
movq %rax, -0xe0(%rbp)
jmp 0x36b94a
leaq -0xc0(%rbp), %rax
movq %rax, -0xe0(%rbp)
jmp 0x36b94a
movq -0xe0(%rbp), %rax
movq %rax, -0xd0(%rbp)
movq -0xd0(%rbp), %rax
movq $0x0, (%rax)
movq -0xc8(%rbp), %rax
movq $0x0, (%rax)
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl -0x28(%rbp), %eax
jae 0x36bb6c
movq -0xc8(%rbp), %rdi
movq -0xd0(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
movl -0x24(%rbp), %r8d
leaq -0x50(%rbp), %r9
leaq -0x58(%rbp), %rbx
leaq -0x60(%rbp), %r11
leaq -0x78(%rbp), %r10
leaq -0x90(%rbp), %rax
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq %rax, 0x18(%rsp)
callq 0x3646f0
addl -0x40(%rbp), %eax
movl %eax, -0x40(%rbp)
movq -0xc8(%rbp), %rdi
movq -0xd0(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
movl -0x24(%rbp), %r8d
leaq -0x50(%rbp), %r9
leaq -0x58(%rbp), %rbx
leaq -0x60(%rbp), %r11
leaq -0x78(%rbp), %r10
leaq -0x90(%rbp), %rax
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movl $0x30, 0x20(%rsp)
movl $0x1, 0x28(%rsp)
callq 0x363d70
addl -0x40(%rbp), %eax
movl %eax, -0x40(%rbp)
movq -0xc8(%rbp), %rdi
movq -0xd0(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
movl -0x24(%rbp), %r8d
leaq -0x50(%rbp), %r9
leaq -0x58(%rbp), %rbx
leaq -0x60(%rbp), %r11
leaq -0x78(%rbp), %r10
leaq -0x90(%rbp), %rax
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movl $0x10, 0x20(%rsp)
movl $0x1, 0x28(%rsp)
callq 0x363d70
addl -0x40(%rbp), %eax
movl %eax, -0x40(%rbp)
movq -0xc8(%rbp), %rdi
movq -0xd0(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x20(%rbp), %rcx
movl -0x24(%rbp), %r8d
leaq -0x50(%rbp), %r9
leaq -0x58(%rbp), %rbx
leaq -0x60(%rbp), %r11
leaq -0x78(%rbp), %r10
leaq -0x90(%rbp), %rax
xorl %r14d, %r14d
movq %rbx, (%rsp)
movq %r11, 0x8(%rsp)
movq %r10, 0x10(%rsp)
movq %rax, 0x18(%rsp)
movl $0x0, 0x20(%rsp)
movl $0x0, 0x28(%rsp)
callq 0x363d70
addl -0x40(%rbp), %eax
movl %eax, -0x40(%rbp)
movq -0x20(%rbp), %rax
movq 0x8(%rax), %rax
shlq %rax
movl %eax, -0x3c(%rbp)
movq -0x50(%rbp), %rdi
movl -0x3c(%rbp), %eax
movl %eax, %esi
shlq $0x0, %rsi
callq 0x2360
movq %rax, -0x50(%rbp)
movq -0x58(%rbp), %rdi
movl -0x3c(%rbp), %eax
movl %eax, %esi
shlq $0x2, %rsi
callq 0x2360
movq %rax, -0x58(%rbp)
movq -0x60(%rbp), %rdi
movl -0x3c(%rbp), %eax
movl %eax, %esi
shlq $0x3, %rsi
callq 0x2360
movq %rax, -0x60(%rbp)
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x58(%rbp), %rdx
movq -0x50(%rbp), %rcx
xorl %r8d, %r8d
callq 0x360ee0
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x36b97b
cmpl $0x0, -0x40(%rbp)
je 0x36bb93
movq -0x20(%rbp), %rdi
callq 0x34d830
movq -0x20(%rbp), %rdi
movl -0x24(%rbp), %esi
movq -0xd0(%rbp), %rcx
movl $0x1, %edx
callq 0x34e170
cmpq $0x0, -0x30(%rbp)
jne 0x36bba6
movq -0x98(%rbp), %rdi
callq 0x2210
cmpq $0x0, -0x38(%rbp)
jne 0x36bbb9
movq -0xb0(%rbp), %rdi
callq 0x2210
movq -0x58(%rbp), %rdi
callq 0x2210
movq -0x60(%rbp), %rdi
callq 0x2210
movq -0x50(%rbp), %rdi
callq 0x2210
movq -0x68(%rbp), %rdi
callq 0x2210
movq -0x80(%rbp), %rdi
callq 0x2210
addq $0x100, %rsp            # imm = 0x100
popq %rbx
popq %r14
popq %rbp
retq
nopw %cs:(%rax,%rax)