// File: chhylp123[P]hifiasm/gfa_ut.cpp
// Function: ul_dp(bubble_type*, all_ul_t*, ubuf_t*, unsigned long*, long, asg_t*, unsigned int, unsigned int, unsigned int)
uint64_t ul_dp(bubble_type* bub, all_ul_t *ul, ubuf_t *b, uint64_t *a, int64_t a_n, asg_t *g, uint32_t v, uint32_t w, uint32_t is_backward)
{
    int64_t i, m, a_i = -1; uc_block_t *p; uint32_t gv; uint64_t url; int64_t we;
    for (i = m = 0; i < a_n; i++) {
        p = &(ul->a[a[i]>>32].bb.a[(uint32_t)(a[i])]);
        assert((!p->base)&&(p->hid == (v>>1))&&(p->el)/**&&(p->pchain)**/);
        if(!p->pchain) continue;
        gv = (((uint32_t)(p->hid))<<1)|((uint32_t)(p->rev));
        if(is_backward) {
            gv ^= 1;
            if(p->pidx == (uint32_t)-1) continue;
        } else {
            if(p->aidx == (uint32_t)-1) continue;
        }
        if(gv != v) continue;
        // fprintf(stderr, "[M::%s::] i:%ld, a_n:%lu, v:%u, w:%u, ulid:%lu, uidx:%u, is_backward:%u\n", 
        // __func__, i, a_n, v, w, a[i]>>32, (uint32_t)(a[i]), is_backward);
        // if(v == 6 && w == 5 && (a[i]>>32) == 95) {
        // int64_t z;
        //     for (z = 0; z < ul->a[a[i]>>32].bb.n; z++) {
        //         fprintf(stderr, "[M::%s::vid->%u] qs:%u, qe:%u, qlen:%u, ts:%u, te:%u, tlen:%u\n", __func__, 
        //         (((uint32_t)(ul->a[a[i]>>32].bb.a[z].hid))<<1)|((uint32_t)(ul->a[a[i]>>32].bb.a[z].rev)), 
        //         ul->a[a[i]>>32].bb.a[z].qs, ul->a[a[i]>>32].bb.a[z].qe, ul->a[a[i]>>32].rlen, 
        //         ul->a[a[i]>>32].bb.a[z].ts, ul->a[a[i]>>32].bb.a[z].te, g->seq[ul->a[a[i]>>32].bb.a[z].hid].len);
        //     }
        // }
        if(ulg_len_check(g, v, p) == 0) continue;///too short
        m++; a_i = i;
    }
    
    if(m == 0) return 0;
    // uint32_t is_debug = (v == 231);
    // if(is_debug) {
    //     fprintf(stderr, "\n+[M::%s::] m->%ld, ulid->%lu\n", __func__, m, a[a_i]>>32);
    // }

    p = &(ul->a[a[a_i]>>32].bb.a[(uint32_t)(a[a_i])]);//longest one
    m = gen_ul_pat_seq(ul->a[a[a_i]>>32].bb.a, &(b->dp), ul, (uint32_t)(a[a_i]), g, v, is_backward, &url);
    assert(b->dp.pat.n > 0);

    // if(is_debug) {
    //     for (i = 0; i < (int64_t)b->dp.pat.n; i++) {
    //         fprintf(stderr, "pat[M::%s::] utg%.6dl(%c), d::%lu\n", __func__, 
    //         (((uint32_t)b->dp.pat.a[i])>>1)+1, "+-"[((uint32_t)b->dp.pat.a[i])&1], b->dp.pat.a[i]>>32);
    //     }
    // }
    if(b->dp.pat.n == 1) return 0;
    gen_ref_pat_seq(g, b, url, UL_TRAV_HERATE, v, w/**, is_debug**/);

    // if(is_debug) {
    //     for (i = 0; i < (int64_t)b->dp.ref.n; i++) {
    //         fprintf(stderr, "ref[M::%s::] utg%.6dl(%c), d::%lu\n", __func__, 
    //         (((uint32_t)b->dp.ref.a[i])>>1)+1, "+-"[((uint32_t)b->dp.ref.a[i])&1], b->dp.ref.a[i]>>32);
    //     }
    // }

    if(!quick_check(ul->a[a[a_i]>>32].bb.a, g, &(b->dp), UL_TRAV_HERATE, UL_TRAV_FT_RATE)) return 0;
    we = ul_dp0(bub, g, &(b->dp), 0.9/**, is_debug**/);
    if(we < 0) return 0;
    return we;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movl 0x20(%rbp), %eax
movl 0x18(%rbp), %eax
movl 0x10(%rbp), %eax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
movq $-0x1, -0x50(%rbp)
movq $0x0, -0x48(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x30(%rbp), %rax
jge 0x3258a3
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq -0x40(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
shrq $0x20, %rcx
imulq $0x58, %rcx, %rcx
addq %rcx, %rax
movq 0x30(%rax), %rax
movq -0x28(%rbp), %rcx
movq -0x40(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movl %ecx, %ecx
imulq $0x24, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movb 0x20(%rax), %cl
shrb $0x6, %cl
andb $0x1, %cl
xorl %eax, %eax
cmpb $0x0, %cl
movb %al, -0x71(%rbp)
jne 0x3257db
movq -0x58(%rbp), %rax
movl (%rax), %ecx
movl 0x10(%rbp), %edx
shrl %edx
xorl %eax, %eax
cmpl %edx, %ecx
movb %al, -0x71(%rbp)
jne 0x3257db
movq -0x58(%rbp), %rax
movb 0x20(%rax), %al
shrb $0x7, %al
cmpb $0x0, %al
setne %al
movb %al, -0x71(%rbp)
movb -0x71(%rbp), %al
testb $0x1, %al
jne 0x3257e4
jmp 0x3257e6
jmp 0x325805
leaq 0x714b3(%rip), %rdi     # 0x396ca0
leaq 0x709c5(%rip), %rsi     # 0x3961b9
movl $0xec3, %edx            # imm = 0xEC3
leaq 0x714c8(%rip), %rcx     # 0x396cc8
callq 0x2130
movq -0x58(%rbp), %rax
movb 0x20(%rax), %al
andb $0x1f, %al
cmpb $0x0, %al
jne 0x325814
jmp 0x325892
movq -0x58(%rbp), %rax
movl (%rax), %eax
shll %eax
movq -0x58(%rbp), %rcx
movb 0x20(%rcx), %cl
shrb $0x5, %cl
andb $0x1, %cl
movzbl %cl, %ecx
orl %ecx, %eax
movl %eax, -0x5c(%rbp)
cmpl $0x0, 0x20(%rbp)
je 0x32584e
movl -0x5c(%rbp), %eax
xorl $0x1, %eax
movl %eax, -0x5c(%rbp)
movq -0x58(%rbp), %rax
cmpl $-0x1, 0x14(%rax)
jne 0x32584c
jmp 0x325892
jmp 0x32585c
movq -0x58(%rbp), %rax
cmpl $-0x1, 0x1c(%rax)
jne 0x32585a
jmp 0x325892
jmp 0x32585c
movl -0x5c(%rbp), %eax
cmpl 0x10(%rbp), %eax
je 0x325866
jmp 0x325892
movq -0x38(%rbp), %rdi
movl 0x10(%rbp), %esi
movq -0x58(%rbp), %rdx
callq 0x322f60
cmpq $0x0, %rax
jne 0x32587e
jmp 0x325892
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x325754
cmpq $0x0, -0x48(%rbp)
jne 0x3258b7
movq $0x0, -0x8(%rbp)
jmp 0x325a54
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq -0x50(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
shrq $0x20, %rcx
imulq $0x58, %rcx, %rcx
addq %rcx, %rax
movq 0x30(%rax), %rax
movq -0x28(%rbp), %rcx
movq -0x50(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movl %ecx, %ecx
imulq $0x24, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq -0x50(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
shrq $0x20, %rcx
imulq $0x58, %rcx, %rcx
addq %rcx, %rax
movq 0x30(%rax), %rdi
movq -0x20(%rbp), %rsi
addq $0x90, %rsi
movq -0x18(%rbp), %rdx
movq -0x28(%rbp), %rax
movq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %eax
movl %eax, %ecx
movq -0x38(%rbp), %r8
movl 0x10(%rbp), %r9d
movl 0x20(%rbp), %r10d
leaq -0x68(%rbp), %rax
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x323160
movq %rax, -0x48(%rbp)
movq -0x20(%rbp), %rax
cmpq $0x0, 0xa8(%rax)
jbe 0x325967
jmp 0x325986
leaq 0x713ca(%rip), %rdi     # 0x396d38
leaq 0x70844(%rip), %rsi     # 0x3961b9
movl $0xee4, %edx            # imm = 0xEE4
leaq 0x71347(%rip), %rcx     # 0x396cc8
callq 0x2130
movq -0x20(%rbp), %rax
cmpq $0x1, 0xa8(%rax)
jne 0x3259a1
movq $0x0, -0x8(%rbp)
jmp 0x325a54
movq -0x38(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x68(%rbp), %rdx
movl 0x10(%rbp), %ecx
movl 0x18(%rbp), %r8d
movsd 0x59654(%rip), %xmm0    # 0x37f010
callq 0x323a80
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq -0x50(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
shrq $0x20, %rcx
imulq $0x58, %rcx, %rcx
addq %rcx, %rax
movq 0x30(%rax), %rdi
movq -0x38(%rbp), %rsi
movq -0x20(%rbp), %rdx
addq $0x90, %rdx
movsd 0x59615(%rip), %xmm0    # 0x37f010
movsd 0x5c82d(%rip), %xmm1    # 0x382230
callq 0x324150
cmpl $0x0, %eax
jne 0x325a17
movq $0x0, -0x8(%rbp)
jmp 0x325a54
movq -0x10(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq -0x20(%rbp), %rdx
addq $0x90, %rdx
movsd 0x5c836(%rip), %xmm0    # 0x382268
callq 0x324c50
movq %rax, -0x70(%rbp)
cmpq $0x0, -0x70(%rbp)
jge 0x325a4c
movq $0x0, -0x8(%rbp)
jmp 0x325a54
movq -0x70(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)