// File: chhylp123[P]hifiasm/Correct.cpp
// Function: ff_lunalign(overlap_region*, double, double, long)
uint32_t inline ff_lunalign(overlap_region *z, double erate, double gap_rate, int64_t max_gap)
{
    if((z->w_list.n == 1) && (!(is_ualn_win(z->w_list.a[0]))) 
        && (z->w_list.a[0].x_start == ((int64_t)z->x_pos_s)) && (z->w_list.a[0].x_end == ((int64_t)z->x_pos_e)) 
            && (z->w_list.a[0].y_start == ((int64_t)z->y_pos_s)) && (z->w_list.a[0].y_end == ((int64_t)z->y_pos_e))) {
                return 1;
    }

    int64_t k, zwn = z->w_list.n, zq, zt, wq, wt, tot_e, tot_g, ql, tl; 

    // fprintf(stderr, "[M::%s]\n", __func__);
    
    zq = z->x_pos_s; zt = z->y_pos_s; tot_e = tot_g = 0; 
    for (k = 0; k < zwn; k++) {
        // fprintf(stderr, "[M::%s]\twk::%ld\tq::[%d, %d)\tt::[%d, %d)\terr::%d\n", __func__, 
        //     k, z->w_list.a[k].x_start, z->w_list.a[k].x_end + 1, z->w_list.a[k].y_start, z->w_list.a[k].y_end + 1, z->w_list.a[k].error);
        if(is_ualn_win(z->w_list.a[k])) continue;
        wq = z->w_list.a[k].x_start; 
        wt = z->w_list.a[k].y_start;

        if(wq != zq) tot_g += ((wq>=zq)?(wq-zq):(zq-wq));
        if(wt != zt) tot_g += ((wt>=zt)?(wt-zt):(zt-wt));

        zq = z->w_list.a[k].x_end + 1; 
        zt = z->w_list.a[k].y_end + 1;
        tot_e += z->w_list.a[k].error;

        // fprintf(stderr, "[M::%s]\twk::%ld\tq::[%d, %d)\tt::[%d, %d)\terr::%d\n", __func__, 
        //     k, z->w_list.a[k].x_start, z->w_list.a[k].x_end + 1, z->w_list.a[k].y_start, z->w_list.a[k].y_end + 1, z->w_list.a[k].error);
    }

    wq = z->x_pos_e + 1;
    wt = z->y_pos_e + 1;
    if(wq != zq) tot_g += ((wq>=zq)?(wq-zq):(zq-wq));
    if(wt != zt) tot_g += ((wt>=zt)?(wt-zt):(zt-wt));

    // fprintf(stderr, "[M::%s]\t%.*s(id::%u)\tq::[%u, %u)\t%.*s(id::%u)\tt::[%u, %u)\tre::%ld\trg::%ld\n", __func__, (int)Get_NAME_LENGTH(R_INF, z->x_id), Get_NAME(R_INF, z->x_id), z->x_id, z->x_pos_s, z->x_pos_e + 1, 
    // (int)Get_NAME_LENGTH(R_INF, z->y_id), Get_NAME(R_INF, z->y_id), z->y_id, z->y_pos_s, z->y_pos_e + 1, tot_e, tot_g);

    if(!tot_g) return 1;

    // fprintf(stderr, "-0-[M::%s]\n", __func__);

    if(tot_g > max_gap) return 0;

    // fprintf(stderr, "-1-[M::%s]\n", __func__);

    ql = z->x_pos_e + 1 - z->x_pos_s;
    tl = z->y_pos_e + 1 - z->y_pos_s;

    if((tot_g > (ql*gap_rate)) || (tot_g > (tl*gap_rate))) return 0;

    // fprintf(stderr, "-2-[M::%s]\n", __func__);

    tot_e += tot_g;

    if((tot_e > (ql*erate)) || (tot_e > (tl*erate))) return 0;

    // fprintf(stderr, "-3-[M::%s]\n", __func__);
    
    return 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x18, %rsp
movq %rdi, -0x10(%rbp)
movsd %xmm0, -0x18(%rbp)
movsd %xmm1, -0x20(%rbp)
movq %rsi, -0x28(%rbp)
movq -0x10(%rbp), %rax
cmpq $0x1, 0x48(%rax)
jne 0xc2156
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movswl 0x14(%rax), %eax
cmpl $0x7fff, %eax           # imm = 0x7FFF
jne 0xc20eb
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
cmpl $0x0, 0x1c(%rax)
jne 0xc20eb
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movswl 0x12(%rax), %eax
cmpl $0x0, %eax
jl 0xc2156
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movslq (%rax), %rax
movq -0x10(%rbp), %rcx
movl 0x4(%rcx), %ecx
cmpq %rcx, %rax
jne 0xc2156
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movslq 0x4(%rax), %rax
movq -0x10(%rbp), %rcx
movl 0x8(%rcx), %ecx
cmpq %rcx, %rax
jne 0xc2156
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movslq 0x8(%rax), %rax
movq -0x10(%rbp), %rcx
movl 0x14(%rcx), %ecx
cmpq %rcx, %rax
jne 0xc2156
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movslq 0xc(%rax), %rax
movq -0x10(%rbp), %rcx
movl 0x18(%rcx), %ecx
cmpq %rcx, %rax
jne 0xc2156
movl $0x1, -0x4(%rbp)
jmp 0xc2495
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movl 0x14(%rax), %eax
movq %rax, -0x48(%rbp)
movq $0x0, -0x68(%rbp)
movq $0x0, -0x60(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x38(%rbp), %rax
jge 0xc2317
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movswl 0x14(%rax), %eax
cmpl $0x7fff, %eax           # imm = 0x7FFF
jne 0xc21f6
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
cmpl $0x0, 0x1c(%rax)
jne 0xc21f6
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movswl 0x12(%rax), %eax
cmpl $0x0, %eax
jge 0xc21f6
jmp 0xc2306
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movslq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movslq 0x8(%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x40(%rbp), %rax
je 0xc2265
movq -0x50(%rbp), %rax
cmpq -0x40(%rbp), %rax
jl 0xc224d
movq -0x50(%rbp), %rax
subq -0x40(%rbp), %rax
movq %rax, -0x80(%rbp)
jmp 0xc2259
movq -0x40(%rbp), %rax
subq -0x50(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
addq -0x68(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x48(%rbp), %rax
je 0xc22a8
movq -0x58(%rbp), %rax
cmpq -0x48(%rbp), %rax
jl 0xc228a
movq -0x58(%rbp), %rax
subq -0x48(%rbp), %rax
movq %rax, -0x88(%rbp)
jmp 0xc2299
movq -0x48(%rbp), %rax
subq -0x58(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x88(%rbp), %rax
addq -0x68(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
addl $0x1, %eax
cltq
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
addl $0x1, %eax
cltq
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x30(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movswq 0x14(%rax), %rax
addq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x30(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x30(%rbp)
jmp 0xc2190
movq -0x10(%rbp), %rax
movl 0x8(%rax), %eax
addl $0x1, %eax
movl %eax, %eax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rax
movl 0x18(%rax), %eax
addl $0x1, %eax
movl %eax, %eax
movq %rax, -0x58(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x40(%rbp), %rax
je 0xc237a
movq -0x50(%rbp), %rax
cmpq -0x40(%rbp), %rax
jl 0xc235c
movq -0x50(%rbp), %rax
subq -0x40(%rbp), %rax
movq %rax, -0x90(%rbp)
jmp 0xc236b
movq -0x40(%rbp), %rax
subq -0x50(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
addq -0x68(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x48(%rbp), %rax
je 0xc23bd
movq -0x58(%rbp), %rax
cmpq -0x48(%rbp), %rax
jl 0xc239f
movq -0x58(%rbp), %rax
subq -0x48(%rbp), %rax
movq %rax, -0x98(%rbp)
jmp 0xc23ae
movq -0x48(%rbp), %rax
subq -0x58(%rbp), %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
addq -0x68(%rbp), %rax
movq %rax, -0x68(%rbp)
cmpq $0x0, -0x68(%rbp)
jne 0xc23d0
movl $0x1, -0x4(%rbp)
jmp 0xc2495
movq -0x68(%rbp), %rax
cmpq -0x28(%rbp), %rax
jle 0xc23e6
movl $0x0, -0x4(%rbp)
jmp 0xc2495
movq -0x10(%rbp), %rax
movl 0x8(%rax), %eax
addl $0x1, %eax
movq -0x10(%rbp), %rcx
subl 0x4(%rcx), %eax
movl %eax, %eax
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rax
movl 0x18(%rax), %eax
addl $0x1, %eax
movq -0x10(%rbp), %rcx
subl 0x14(%rcx), %eax
movl %eax, %eax
movq %rax, -0x78(%rbp)
cvtsi2sdq -0x68(%rbp), %xmm0
cvtsi2sdq -0x70(%rbp), %xmm1
mulsd -0x20(%rbp), %xmm1
ucomisd %xmm1, %xmm0
ja 0xc2442
cvtsi2sdq -0x68(%rbp), %xmm0
cvtsi2sdq -0x78(%rbp), %xmm1
mulsd -0x20(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0xc244b
movl $0x0, -0x4(%rbp)
jmp 0xc2495
movq -0x68(%rbp), %rax
addq -0x60(%rbp), %rax
movq %rax, -0x60(%rbp)
cvtsi2sdq -0x60(%rbp), %xmm0
cvtsi2sdq -0x70(%rbp), %xmm1
mulsd -0x18(%rbp), %xmm1
ucomisd %xmm1, %xmm0
ja 0xc2485
cvtsi2sdq -0x60(%rbp), %xmm0
cvtsi2sdq -0x78(%rbp), %xmm1
mulsd -0x18(%rbp), %xmm1
ucomisd %xmm1, %xmm0
jbe 0xc248e
movl $0x0, -0x4(%rbp)
jmp 0xc2495
movl $0x1, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x18, %rsp
popq %rbp
retq
nop