// File: chhylp123[P]hifiasm/Correct.cpp
// Function: hc_aln_exz_non_retrieve_adv_hc(overlap_region*, char*, char*, long, long, long, long, long, long, bit_extz_t*, long, long, double, long, long, long, long, overlap_region*)
int64_t hc_aln_exz_non_retrieve_adv_hc(overlap_region *z, char* qstr, char* tstr, int64_t qs, int64_t qe, int64_t ts, int64_t te, int64_t mode, int64_t wl, 
bit_extz_t *exz, int64_t q_tot, int64_t t_tot, double e_rate, int64_t maxl, int64_t maxe, int64_t force_l, int64_t estimate_err, overlap_region *aux_o)
{
    clear_align(*exz); exz->thre = 0; 
    if(((ts == -1) && (te == -1))) mode = 3;///set to semi-global
    int64_t thre, ql = qe - qs, thre0, pthre = -1, full = 0;
    if(ql == 0 && (te-ts) == 0) return 1;
    if((ql <= 0) || (te-ts) <= 0) return 0;
    if(estimate_err < 0) estimate_err = cal_estimate_err_hc(z, wl, qs, qe, ts, te, e_rate, &full);
    

    
    // if(ql <= 16) {
    if(estimate_err == 0) {
        if(full) {
            // if(!cal_exact_exz(z, uref, hpc_g, rref, exz, qstr, tu, qs, qe, ts, te, &pts, &pte, q_tot, mode)) {
            //     fprintf(stderr, "[M::%s::ql::%ld::%c] xid::%d, yid::%d, qs::[%ld, %ld), ts::[%ld, %ld), mode::%ld, est_err::%ld, e_rate::%f, maxe::%ld\n", 
            //                                             __func__, ql, "+-"[z->y_pos_strand], z->x_id, z->y_id, qs, qe, ts, te, mode, estimate_err, e_rate, maxe);
            //     exit(1);
            // }
            set_exact_exz(exz, qs, qe, ts, te); push_alnw(aux_o, exz);
            return 1;
        } else if(cal_exact_non_retrieve_exz(z, exz, qstr, tstr, qs, qe, ts, te, q_tot, t_tot, mode)) {
            // ref_cigar_check(qstr, tu, uref, hpc_g, rref, z->y_id, z->y_pos_strand, exz);
            // fprintf(stderr, ", err::%d, thre::%d, scale::0(+)\n", exz->err, exz->thre);
            push_alnw(aux_o, exz);
            return 1;
        }
    }

    if(ql <= maxl && (estimate_err>>1) <= maxe) {
        thre = scale_ed_thre(estimate_err, maxe); 
        if(cal_exz_infi_non_retrieve_adv(z, exz, qstr, tstr, qs, qe, ts, te, thre, &pthre, q_tot, t_tot, mode)) {
            // ref_cigar_check(qstr, tu, uref, hpc_g, rref, z->y_id, z->y_pos_strand, exz);
            // fprintf(stderr, ", err::%d, thre::%d, scale::%ld(+)\n", exz->err, exz->thre, thre);
            push_alnw(aux_o, exz);
            return 1;
        }

        thre0 = thre; thre = ql*e_rate; thre = scale_ed_thre(thre, maxe); 
        if(thre > thre0) {
            if(cal_exz_infi_non_retrieve_adv(z, exz, qstr, tstr, qs, qe, ts, te, thre, &pthre, q_tot, t_tot, mode)) {
                // ref_cigar_check(qstr, tu, uref, hpc_g, rref, z->y_id, z->y_pos_strand, exz);
                // fprintf(stderr, ", err::%d, thre::%d, scale::%ld(-)\n", exz->err, exz->thre, thre);
                push_alnw(aux_o, exz);
                return 1;
            }
        }

        thre0 = thre; thre <<= 1; thre = scale_ed_thre(thre, maxe); 
        if(thre > thre0) {
            if(cal_exz_infi_non_retrieve_adv(z, exz, qstr, tstr, qs, qe, ts, te, thre, &pthre, q_tot, t_tot, mode)) {
                // ref_cigar_check(qstr, tu, uref, hpc_g, rref, z->y_id, z->y_pos_strand, exz);
                // fprintf(stderr, ", err::%d, thre::%d, scale::%ld(-)\n", exz->err, exz->thre, thre);
                push_alnw(aux_o, exz);
                return 1;
            }
        }

        thre0 = thre; thre = ql*0.51; thre = scale_ed_thre(thre, maxe); 
        if(thre > thre0) {
            if(cal_exz_infi_non_retrieve_adv(z, exz, qstr, tstr, qs, qe, ts, te, thre, &pthre, q_tot, t_tot, mode)) {
                // ref_cigar_check(qstr, tu, uref, hpc_g, rref, z->y_id, z->y_pos_strand, exz);
                // fprintf(stderr, ", err::%d, thre::%d, scale::%ld(*)\n", exz->err, exz->thre, thre);
                push_alnw(aux_o, exz);
                return 1;
            }
        }

        if(ql <= force_l) {
            thre = maxe; 
            if(cal_exz_infi_non_retrieve_adv(z, exz, qstr, tstr, qs, qe, ts, te, thre, &pthre, q_tot, t_tot, mode)) {
                // ref_cigar_check(qstr, tu, uref, hpc_g, rref, z->y_id, z->y_pos_strand, exz);
                // fprintf(stderr, ", err::%d, thre::%d, scale::%ld(*)\n", exz->err, exz->thre, thre);
                push_alnw(aux_o, exz);
                return 1;
            }
        }
    }
    // fprintf(stderr, ", err::%d, thre::%d\n", INT32_MAX, exz->thre);
    // if(mode == 0) {
    //     fprintf(stderr, "[M::%s::] pstr::%.*s\n", __func__, (int32_t)tu->length, tu->seq);
    //     fprintf(stderr, "[M::%s::] tstr::%.*s\n", __func__, (int32_t)(qe-qs), qstr+qs);
    // }
    return 0;
    
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0xa0, %rsp
movq 0x60(%rbp), %rax
movq 0x58(%rbp), %rax
movq 0x50(%rbp), %rax
movq 0x48(%rbp), %rax
movq 0x40(%rbp), %rax
movq 0x38(%rbp), %rax
movq 0x30(%rbp), %rax
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x30(%rbp)
movq %rsi, -0x38(%rbp)
movq %rdx, -0x40(%rbp)
movq %rcx, -0x48(%rbp)
movq %r8, -0x50(%rbp)
movq %r9, -0x58(%rbp)
movsd %xmm0, -0x60(%rbp)
movq 0x28(%rbp), %rax
movl $0x7fffffff, 0x2c(%rax) # imm = 0x7FFFFFFF
movq 0x28(%rbp), %rax
movl $0x0, 0x28(%rax)
cmpq $-0x1, -0x58(%rbp)
jne 0x623f7
cmpq $-0x1, 0x10(%rbp)
jne 0x623f7
movq $0x3, 0x18(%rbp)
movq -0x50(%rbp), %rax
subq -0x48(%rbp), %rax
movq %rax, -0x70(%rbp)
movq $-0x1, -0x80(%rbp)
movq $0x0, -0x88(%rbp)
cmpq $0x0, -0x70(%rbp)
jne 0x62438
movq 0x10(%rbp), %rax
subq -0x58(%rbp), %rax
cmpq $0x0, %rax
jne 0x62438
movq $0x1, -0x28(%rbp)
jmp 0x628b6
cmpq $0x0, -0x70(%rbp)
jle 0x6244d
movq 0x10(%rbp), %rax
subq -0x58(%rbp), %rax
cmpq $0x0, %rax
jg 0x6245a
movq $0x0, -0x28(%rbp)
jmp 0x628b6
cmpq $0x0, 0x58(%rbp)
jge 0x62492
movq -0x30(%rbp), %rdi
movq 0x20(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq -0x50(%rbp), %rcx
movq -0x58(%rbp), %r8
movq 0x10(%rbp), %r9
movsd -0x60(%rbp), %xmm0
leaq -0x88(%rbp), %rax
movq %rax, (%rsp)
callq 0x5e0e0
movq %rax, 0x58(%rbp)
cmpq $0x0, 0x58(%rbp)
jne 0x62547
cmpq $0x0, -0x88(%rbp)
je 0x624da
movq 0x28(%rbp), %rdi
movq -0x48(%rbp), %rsi
movq -0x50(%rbp), %rdx
movq -0x58(%rbp), %rcx
movq 0x10(%rbp), %r8
callq 0x61ae0
movq 0x60(%rbp), %rdi
movq 0x28(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x28(%rbp)
jmp 0x628b6
movq -0x30(%rbp), %rdi
movq 0x28(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0x50(%rbp), %r9
movq -0x58(%rbp), %r14
movq 0x10(%rbp), %rbx
movq 0x30(%rbp), %r11
movq 0x38(%rbp), %r10
movq 0x18(%rbp), %rax
movq %r14, (%rsp)
movq %rbx, 0x8(%rsp)
movq %r11, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movq %rax, 0x20(%rsp)
callq 0x5fbd0
cmpq $0x0, %rax
je 0x62543
movq 0x60(%rbp), %rdi
movq 0x28(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x28(%rbp)
jmp 0x628b6
jmp 0x62545
jmp 0x62547
movq -0x70(%rbp), %rax
cmpq 0x40(%rbp), %rax
jg 0x628ae
movq 0x58(%rbp), %rax
sarq %rax
cmpq 0x48(%rbp), %rax
jg 0x628ae
movq 0x58(%rbp), %rax
movl %eax, %edi
movq 0x48(%rbp), %rax
movl %eax, %esi
callq 0xb7290
movq %rax, -0x68(%rbp)
movq -0x30(%rbp), %rdi
movq 0x28(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0x50(%rbp), %r9
movq -0x58(%rbp), %r12
movq 0x10(%rbp), %r15
movq -0x68(%rbp), %r14
movq 0x30(%rbp), %r11
movq 0x38(%rbp), %r10
movq 0x18(%rbp), %rax
leaq -0x80(%rbp), %rbx
movq %r12, (%rsp)
movq %r15, 0x8(%rsp)
movq %r14, 0x10(%rsp)
movq %rbx, 0x18(%rsp)
movq %r11, 0x20(%rsp)
movq %r10, 0x28(%rsp)
movq %rax, 0x30(%rsp)
callq 0x5f4e0
cmpq $0x0, %rax
je 0x625f6
movq 0x60(%rbp), %rdi
movq 0x28(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x28(%rbp)
jmp 0x628b6
movq -0x68(%rbp), %rax
movq %rax, -0x78(%rbp)
cvtsi2sdq -0x70(%rbp), %xmm0
mulsd -0x60(%rbp), %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movl %eax, %edi
movq 0x48(%rbp), %rax
movl %eax, %esi
callq 0xb7290
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
cmpq -0x78(%rbp), %rax
jle 0x626ae
movq -0x30(%rbp), %rdi
movq 0x28(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0x50(%rbp), %r9
movq -0x58(%rbp), %r12
movq 0x10(%rbp), %r15
movq -0x68(%rbp), %r14
movq 0x30(%rbp), %r11
movq 0x38(%rbp), %r10
movq 0x18(%rbp), %rax
leaq -0x80(%rbp), %rbx
movq %r12, (%rsp)
movq %r15, 0x8(%rsp)
movq %r14, 0x10(%rsp)
movq %rbx, 0x18(%rsp)
movq %r11, 0x20(%rsp)
movq %r10, 0x28(%rsp)
movq %rax, 0x30(%rsp)
callq 0x5f4e0
cmpq $0x0, %rax
je 0x626ac
movq 0x60(%rbp), %rdi
movq 0x28(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x28(%rbp)
jmp 0x628b6
jmp 0x626ae
movq -0x68(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x68(%rbp), %rax
shlq %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movl %eax, %edi
movq 0x48(%rbp), %rax
movl %eax, %esi
callq 0xb7290
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
cmpq -0x78(%rbp), %rax
jle 0x6275d
movq -0x30(%rbp), %rdi
movq 0x28(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0x50(%rbp), %r9
movq -0x58(%rbp), %r12
movq 0x10(%rbp), %r15
movq -0x68(%rbp), %r14
movq 0x30(%rbp), %r11
movq 0x38(%rbp), %r10
movq 0x18(%rbp), %rax
leaq -0x80(%rbp), %rbx
movq %r12, (%rsp)
movq %r15, 0x8(%rsp)
movq %r14, 0x10(%rsp)
movq %rbx, 0x18(%rsp)
movq %r11, 0x20(%rsp)
movq %r10, 0x28(%rsp)
movq %rax, 0x30(%rsp)
callq 0x5f4e0
cmpq $0x0, %rax
je 0x6275b
movq 0x60(%rbp), %rdi
movq 0x28(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x28(%rbp)
jmp 0x628b6
jmp 0x6275d
movq -0x68(%rbp), %rax
movq %rax, -0x78(%rbp)
cvtsi2sdq -0x70(%rbp), %xmm0
movsd 0x31fb45(%rip), %xmm1   # 0x3822b8
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movl %eax, %edi
movq 0x48(%rbp), %rax
movl %eax, %esi
callq 0xb7290
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
cmpq -0x78(%rbp), %rax
jle 0x6281c
movq -0x30(%rbp), %rdi
movq 0x28(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0x50(%rbp), %r9
movq -0x58(%rbp), %r12
movq 0x10(%rbp), %r15
movq -0x68(%rbp), %r14
movq 0x30(%rbp), %r11
movq 0x38(%rbp), %r10
movq 0x18(%rbp), %rax
leaq -0x80(%rbp), %rbx
movq %r12, (%rsp)
movq %r15, 0x8(%rsp)
movq %r14, 0x10(%rsp)
movq %rbx, 0x18(%rsp)
movq %r11, 0x20(%rsp)
movq %r10, 0x28(%rsp)
movq %rax, 0x30(%rsp)
callq 0x5f4e0
cmpq $0x0, %rax
je 0x6281a
movq 0x60(%rbp), %rdi
movq 0x28(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x28(%rbp)
jmp 0x628b6
jmp 0x6281c
movq -0x70(%rbp), %rax
cmpq 0x50(%rbp), %rax
jg 0x628ac
movq 0x48(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x30(%rbp), %rdi
movq 0x28(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
movq -0x48(%rbp), %r8
movq -0x50(%rbp), %r9
movq -0x58(%rbp), %r12
movq 0x10(%rbp), %r15
movq -0x68(%rbp), %r14
movq 0x30(%rbp), %r11
movq 0x38(%rbp), %r10
movq 0x18(%rbp), %rax
leaq -0x80(%rbp), %rbx
movq %r12, (%rsp)
movq %r15, 0x8(%rsp)
movq %r14, 0x10(%rsp)
movq %rbx, 0x18(%rsp)
movq %r11, 0x20(%rsp)
movq %r10, 0x28(%rsp)
movq %rax, 0x30(%rsp)
callq 0x5f4e0
cmpq $0x0, %rax
je 0x628aa
movq 0x60(%rbp), %rdi
movq 0x28(%rbp), %rsi
callq 0x60af0
movq $0x1, -0x28(%rbp)
jmp 0x628b6
jmp 0x628ac
jmp 0x628ae
movq $0x0, -0x28(%rbp)
movq -0x28(%rbp), %rax
addq $0xa0, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nopw (%rax,%rax)