// File: /workspace/github_cpp_makefile_star2_O3/chhylp123[P]hifiasm/Correct.cpp
// Function: tuning_ext_offset(overlap_region*, k_mer_hit*, long, long, long, long, long, long, long*, long*, long*, long*, long*, long*, long*)
void tuning_ext_offset(overlap_region *z, k_mer_hit *ch_a, int64_t ch_n, int64_t ql, int64_t tl, int64_t wl, 
int64_t fusion_k_len, int64_t fusion_win_occ, int64_t *ch_s0, int64_t *ch_e0, int64_t *qs0, int64_t *qe0, int64_t *ts0, int64_t *te0, int64_t *mode)
{
    ///[qs, qe)
    if((*mode) != 1 && (*mode) != 2) return;
    int64_t qs = *qs0, qe = *qe0, ts = *ts0, te = *te0, ch_s = *ch_s0, ch_e = *ch_e0;
    int64_t ke, ks, p[3], we, ws, k, wid;
    int64_t sl, gq, gt, gl, gg, update, min_g = INT32_MAX, min_id = -1;
    adjust_ext_offset(&qs, &qe, &ts, &te, ql, tl, 0, *mode); p[0] = p[1] = p[2] = -1;
    if((*mode) == 1) {///forward extension
        //qs0 and ts0 are fixed; te0 = -1, qe0 is unreliable
        if(qe > (*qe0)) {
            ///find k-mer hit
            ke = ch_a[ch_s].self_offset;
            for (ch_e = ch_s; (ch_e < ch_n) && (ch_a[ch_e].self_offset < (*qe0)); ch_e++) {
                ke = ch_a[ch_e].self_offset;
            }
            for (ke += fusion_k_len; (ch_e < ch_n) && (ch_a[ch_e].self_offset < ke); ch_e++) {
                if(ch_a[ch_e].self_offset<(*qe0)) continue;
                if((ch_a[ch_e].offset<=(*ts0))||(ch_a[ch_e].self_offset<=(*qs0))) continue;//not co-linear
                if(is_pri_aln(ch_a[ch_e])) {
                    p[2] = ch_e; break;
                } else if(ch_a[ch_e].cnt > 1 && p[1] == -1) {
                    p[1] = ch_e;
                } else if(p[0] == -1) {
                    p[0] = ch_e;
                }
            }
            if(p[2] != -1) p[0] = p[2];
            else if(p[1] != -1) p[0] = p[1];
            if(p[0] != -1) {
                (*mode) = 0;///global
                (*qe0) = ch_a[p[0]].self_offset; (*te0) = ch_a[p[0]].offset; (*ch_e0) = p[0];
                return;
            }

            ///find aligned window
            we = (*qe0); we/=wl; we *= wl; we +=wl; we--; ///next window
            for (k = 0; we < qe && we <= z->x_pos_e && k < fusion_win_occ; we+=wl) {//[ws, we]; [qs, qe)
                wid = get_win_id_by_e(z, we, wl, NULL);
                if(z->w_list.a[wid].y_end == -1) continue;//unmapped
                if(z->w_list.a[wid].x_end < (*qs0)) continue;
                if(z->w_list.a[wid].y_end < (*ts0)) continue;
                sl = z->w_list.a[wid].x_end+1-z->w_list.a[wid].x_start;
                if(z->w_list.a[wid].error > (sl/A_L)) continue;
                gq = z->w_list.a[wid].x_end-(*qs0); 
                gt = z->w_list.a[wid].y_end-(*ts0); 
                gl = MIN(gq, gt); gl/=16; if(gl <= 0) gl = 1;
                gg = (gq>=gt)?(gq-gt):(gt-gq); gg /= gl;
                update = 0;
                if(min_g>gg) {
                    update = 1;
                } else if((min_g==gg)&&(z->w_list.a[min_id].error>z->w_list.a[wid].error)) {
                    update = 1;
                } 
                if(update) {
                    min_g = gg; min_id = wid;
                }
                k++;
            }
        }

        if(min_id != -1) {
            (*qe0) = z->w_list.a[min_id].x_end+1; 
            (*te0) = z->w_list.a[min_id].y_end+1; 
            (*mode) = 0;///global
        } else {
            (*qe0) = qe; (*te0) = te;//extension
        }
    } else if((*mode) == 2) {///backward extension
        //qe0 and te0 are fixed; ts0 = -1, qs0 is unreliable
        if(qs < (*qs0)) {
            ///find k-mer hit
            ks = ch_a[ch_e].self_offset;
            for (ch_s = ch_e; (ch_s >= 0) && (ch_a[ch_s].self_offset > (*qs0)); ch_s--) {
                ks = ch_a[ch_s].self_offset;
            }
            for (ks -= fusion_k_len; (ch_s >= 0) && (ch_a[ch_s].self_offset > ks); ch_s--) {
                if(ch_a[ch_s].self_offset>(*qs0)) continue;
                if((ch_a[ch_s].offset>=(*te0))||(ch_a[ch_s].self_offset>=(*qe0))) continue;//not co-linear
                if(is_pri_aln(ch_a[ch_s])) {
                    p[2] = ch_s; break;
                } else if(ch_a[ch_s].cnt > 1 && p[1] == -1) {
                    p[1] = ch_s;
                } else if(p[0] == -1) {
                    p[0] = ch_s;
                }
            }
            // fprintf(stderr, "-[M::%s::] utg%.6dl(%c), p[0]::%ld, p[1]::%ld, p[2]::%ld\n", 
            //             __func__, (int32_t)z->y_id+1, "+-"[z->y_pos_strand], p[0], p[1], p[2]);
            if(p[2] != -1) p[0] = p[2];
            else if(p[1] != -1) p[0] = p[1];
            if(p[0] != -1) {
                (*mode) = 0;///global
                (*qs0) = ch_a[p[0]].self_offset; (*ts0) = ch_a[p[0]].offset; (*ch_s0) = p[0];
                return;
            }

            ///find aligned window
            ws = (*qs0)-1; ws/=wl; ws*=wl; 
            for (k = 0; ws >= qs && ws >= z->x_pos_s && k < fusion_win_occ; ws-=wl) {//[ws, we]; [qs, qe)
                wid = get_win_id_by_s(z, ws, wl, NULL);
                if(z->w_list.a[wid].y_end == -1) continue;//unmapped
                if(z->w_list.a[wid].x_start >= (*qe0)) continue;
                if(z->w_list.a[wid].y_start >= (*te0)) continue;
                sl = z->w_list.a[wid].x_end+1-z->w_list.a[wid].x_start;
                if(z->w_list.a[wid].error > (sl/A_L)) continue;
                gq = (*qe0) - z->w_list.a[wid].x_start; 
                gt = (*te0) - z->w_list.a[wid].y_start; 
                gl = MIN(gq, gt); gl/=16; if(gl <= 0) gl = 1;
                gg = (gq>=gt)?(gq-gt):(gt-gq); gg /= gl;
                update = 0;
                if(min_g>gg) {
                    update = 1;
                } else if((min_g==gg)&&(z->w_list.a[min_id].error>z->w_list.a[wid].error)) {
                    update = 1;
                } 
                if(update) {
                    min_g = gg; min_id = wid;
                }
                k++;
            }
        }

        if(min_id != -1) {
            (*qs0) = z->w_list.a[min_id].x_start; 
            (*ts0) = z->w_list.a[min_id].y_start; 
            (*mode) = 0;///global
        } else {
            (*qs0) = qs; (*ts0) = ts; ///still extension
        }
    }

    if((*ch_e0) == -1) {
        for ((*ch_e0)=(*ch_s0);((*ch_e0)<ch_n)&&(ch_a[(*ch_e0)].self_offset>=(*qs0))&&(ch_a[(*ch_e0)].self_offset<=(*qe0)); (*ch_e0)++);
    }

    if((*ch_s0) == -1) {
        for ((*ch_s0)=(*ch_e0);((*ch_s0)>=0)&&(ch_a[(*ch_s0)].self_offset>=(*qs0))&&(ch_a[(*ch_s0)].self_offset<=(*qe0)); (*ch_s0)--);
        (*ch_s0)++;
    }
    ///boundry
    for (;((*ch_e0)<ch_n)&&(ch_a[(*ch_e0)].self_offset>=(*qs0))&&(ch_a[(*ch_e0)].self_offset<=(*qe0)); (*ch_e0)++);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rdi, -0x10(%rsp)
movq 0x78(%rsp), %rax
movq (%rax), %r13
leaq -0x1(%r13), %rax
cmpq $0x1, %rax
ja 0x638f9
movq %rdx, %rbx
movq 0x70(%rsp), %r14
movq 0x68(%rsp), %r15
movq 0x60(%rsp), %rdx
movq 0x58(%rsp), %rax
movq 0x50(%rsp), %rdi
movq 0x48(%rsp), %r10
movq (%rax), %r11
movq (%rdx), %r12
movq (%r15), %rbp
movq (%r14), %r14
movq (%r10), %rdx
movq (%rdi), %rax
cmpq $0x1, %r13
movq %rsi, -0x18(%rsp)
movq %rbp, -0x30(%rsp)
movq %r14, -0x20(%rsp)
jne 0x63245
movq %rcx, %rsi
subq %r11, %rsi
movq %r8, %r15
subq %rbp, %r15
cmpq %r15, %rsi
jle 0x6325b
addq %r11, %r15
movq %r11, %r10
movq %r8, %rsi
jmp 0x63264
movq %r12, %r10
subq %r14, %r10
jle 0x63374
xorl %ebp, %ebp
movq %r12, %r15
movq %r14, %rsi
jmp 0x63264
addq %rbp, %rsi
movq %r11, %r10
movq %rcx, %r15
xorl %r14d, %r14d
testq %r10, %r10
cmovleq %r14, %r10
testq %rbp, %rbp
cmovgq %rbp, %r14
cmpq %rcx, %r15
cmovlq %r15, %rcx
cmpq %r8, %rsi
cmovlq %rsi, %r8
cmpq $0x1, %r13
jne 0x63381
cmpq %r12, %rcx
jle 0x6380a
movq %rdx, %rsi
shlq $0x4, %rsi
movq -0x18(%rsp), %r14
movl 0x8(%r14,%rsi), %eax
cmpq %rbx, %rdx
jge 0x632dc
movl 0x8(%r14,%rsi), %r10d
cmpq %r10, %r12
jle 0x632dc
addq %r14, %rsi
addq $0x18, %rsi
leaq -0x1(%rbx), %rdi
cmpq %rdx, %rdi
je 0x6368e
movq %r10, %rax
movl (%rsi), %r10d
addq $0x10, %rsi
incq %rdx
cmpq %r10, %r12
jg 0x632c1
cmpq %rbx, %rdx
jge 0x6368e
addq 0x38(%rsp), %rax
movq %rdx, %rsi
shlq $0x4, %rsi
addq %rsi, %r14
addq $0xc, %r14
movq $-0x1, %rsi
movl $0x7fffffff, %r13d      # imm = 0x7FFFFFFF
movq $-0x1, %r10
movl -0x4(%r14), %edi
cmpq %rdi, %rax
jle 0x63643
cmpq %rdi, %r12
jle 0x6332f
incq %rdx
addq $0x10, %r14
cmpq %rdx, %rbx
jne 0x6330c
jmp 0x63643
cmpq %rdi, %r11
jge 0x6331e
movl -0x8(%r14), %edi
cmpq %rdi, -0x30(%rsp)
jge 0x6331e
movl -0xc(%r14), %edi
andl %r13d, %edi
cmpl %r13d, %edi
je 0x63904
movl (%r14), %ebp
cmpl %edi, %ebp
jae 0x63904
cmpl $0x2, %ebp
jb 0x6336a
cmpq $-0x1, %r10
jne 0x6336a
movq %rdx, %r10
jmp 0x6331e
cmpq $-0x1, %rsi
cmoveq %rdx, %rsi
jmp 0x6331e
subq %r12, %r14
xorl %r10d, %r10d
testq %r14, %r14
cmovleq %r10, %r14
cmpq %r11, %r10
jge 0x63629
testq %rax, %rax
js 0x634a8
movq %rax, %rdx
shlq $0x4, %rdx
movq -0x18(%rsp), %rsi
movl 0x8(%rsi,%rdx), %ecx
cmpq %rcx, %r11
jge 0x633cc
addq %rsi, %rdx
addq $-0x8, %rdx
movq %rcx, %rsi
testq %rax, %rax
jle 0x634a8
movq %rsi, %rcx
decq %rax
movl (%rdx), %esi
addq $-0x10, %rdx
cmpq %rsi, %r11
jl 0x633b2
subq 0x38(%rsp), %rcx
movq %rax, %rdx
shlq $0x4, %rdx
movq -0x18(%rsp), %rsi
leaq (%rdx,%rsi), %r13
addq $0xc, %r13
movq $-0x1, %rdx
movq $-0x1, %r8
movl -0x4(%r13), %r15d
cmpq %r15, %rcx
jge 0x63459
cmpq %r15, %r11
jl 0x63449
movl -0x8(%r13), %esi
cmpq %rsi, -0x20(%rsp)
setle %dil
cmpq %r15, %r12
setle %bpl
orb %dil, %bpl
jne 0x63449
movl -0xc(%r13), %edi
movl $0x7fffffff, %ebp       # imm = 0x7FFFFFFF
andl %ebp, %edi
cmpl %ebp, %edi
je 0x6347f
movl (%r13), %ebp
cmpl %edi, %ebp
jae 0x6347f
cmpl $0x2, %ebp
jb 0x63441
cmpq $-0x1, %r8
jne 0x63441
movq %rax, %r8
jmp 0x63449
cmpq $-0x1, %rdx
cmoveq %rax, %rdx
leaq -0x1(%rax), %rsi
addq $-0x10, %r13
testq %rax, %rax
movq %rsi, %rax
jg 0x633f3
cmpq $-0x1, %r8
movq %rdx, %rax
cmovneq %r8, %rax
cmpq $-0x1, %rax
je 0x634a8
movq %rax, %rcx
shlq $0x4, %rcx
movq -0x18(%rsp), %rdx
movl 0x4(%rdx,%rcx), %esi
movl 0x8(%rdx,%rcx), %r15d
movq 0x78(%rsp), %rcx
movq $0x0, (%rcx)
movq 0x58(%rsp), %rcx
movq %r15, (%rcx)
movq 0x68(%rsp), %rcx
movq %rsi, (%rcx)
movq 0x48(%rsp), %rcx
movq %rax, (%rcx)
jmp 0x638f9
decq %r11
movq %r11, %rax
cqto
idivq %r9
subq %rdx, %r11
cmpq %r10, %r11
jl 0x63629
movq -0x10(%rsp), %rax
movl 0x4(%rax), %ecx
movq %rcx, %rbp
negq %rbp
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movq %rax, -0x8(%rsp)
movq $-0x1, -0x28(%rsp)
xorl %r13d, %r13d
movq %rbp, -0x30(%rsp)
cmpq %rcx, %r11
jl 0x635ea
cmpq 0x40(%rsp), %r13
jge 0x635ea
movq %rcx, %rax
xorl %edx, %edx
idivq %r9
leaq (%r11,%rbp), %rax
addq %rdx, %rax
cqto
idivq %r9
movq %rax, %r8
movq -0x10(%rsp), %rax
movq 0x58(%rax), %r15
movq %r8, %rsi
shlq $0x5, %rsi
cmpl $-0x1, 0xc(%r15,%rsi)
je 0x635de
addq %r15, %rsi
movslq (%rsi), %rdi
movq %r12, %rax
subq %rdi, %rax
jle 0x635de
movslq 0x8(%rsi), %rbp
movq -0x20(%rsp), %rdx
subq %rbp, %rdx
jle 0x6356a
movl 0x4(%rsi), %ebp
subl %edi, %ebp
leal 0x1(%rbp), %edi
movswl 0x14(%rsi), %esi
addl $0x10, %ebp
testl %edi, %edi
cmovnsl %edi, %ebp
sarl $0x4, %ebp
cmpl %esi, %ebp
jge 0x63571
movq -0x30(%rsp), %rbp
jmp 0x635de
movq %rax, %rdi
subq %rdx, %rdi
cmovlq %rax, %rdx
leaq 0xf(%rdx), %rbp
testq %rdx, %rdx
cmovnsq %rdx, %rbp
sarq $0x4, %rbp
cmpq $0x2, %rbp
movl $0x1, %eax
cmovlq %rax, %rbp
movq %rdi, %rax
negq %rax
cmovsq %rdi, %rax
xorl %edx, %edx
divq %rbp
cmpq %rax, -0x8(%rsp)
jle 0x635b9
movq %rax, -0x8(%rsp)
movq %r8, -0x28(%rsp)
jmp 0x635d6
jne 0x635d6
movq -0x28(%rsp), %rdx
movq %rdx, %rax
shlq $0x5, %rax
cmpw %si, 0x14(%r15,%rax)
cmovgq %r8, %rdx
movq %rdx, -0x28(%rsp)
movq -0x30(%rsp), %rbp
incq %r13
subq %r9, %r11
cmpq %r10, %r11
jge 0x634e8
movq -0x28(%rsp), %rdx
cmpq $-0x1, %rdx
je 0x63629
movq -0x10(%rsp), %rax
movq 0x58(%rax), %rax
shlq $0x5, %rdx
movslq (%rax,%rdx), %rcx
movq 0x58(%rsp), %rsi
movq %rcx, (%rsi)
movslq 0x8(%rax,%rdx), %rax
movq 0x68(%rsp), %rcx
movq %rax, (%rcx)
movq 0x78(%rsp), %rax
movq $0x0, (%rax)
jmp 0x63639
movq 0x58(%rsp), %rsi
movq %r10, (%rsi)
movq 0x68(%rsp), %rax
movq %r14, (%rax)
movq 0x60(%rsp), %r9
jmp 0x6381f
cmpq $-0x1, %r10
cmovneq %r10, %rsi
cmpq $-0x1, %rsi
movq -0x18(%rsp), %rdi
je 0x6368e
movq 0x78(%rsp), %rax
movq $0x0, (%rax)
movq %rsi, %rax
shlq $0x4, %rax
movl 0x8(%rdi,%rax), %ecx
movq 0x60(%rsp), %rdx
movq %rcx, (%rdx)
movl 0x4(%rdi,%rax), %eax
movq 0x70(%rsp), %rcx
movq %rax, (%rcx)
movq 0x50(%rsp), %rax
movq %rsi, (%rax)
jmp 0x638f9
movq %r12, %rax
cqto
idivq %r9
movq %rdx, %r14
addq %r9, %r12
notq %r14
addq %r12, %r14
cmpq %rcx, %r14
jge 0x6380a
movq -0x10(%rsp), %rax
movl 0x8(%rax), %r12d
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
movq %rax, -0x28(%rsp)
movq $-0x1, -0x20(%rsp)
xorl %esi, %esi
cmpq %r12, %r14
jg 0x637c4
cmpq 0x40(%rsp), %rsi
jge 0x637c4
movq -0x10(%rsp), %rdi
movl 0x4(%rdi), %r10d
movq %r10, %rax
xorl %edx, %edx
idivq %r9
subq %r10, %rdx
leaq (%rdx,%r14), %rax
cqto
idivq %r9
movq %rax, %r10
movq 0x58(%rdi), %r15
movq %rax, %rdi
shlq $0x5, %rdi
movslq 0xc(%r15,%rdi), %rax
cmpq $-0x1, %rax
je 0x637b8
addq %r15, %rdi
movslq 0x4(%rdi), %rbp
movq %rbp, %rdx
subq %r11, %rdx
jl 0x637b8
subq -0x30(%rsp), %rax
jl 0x637b8
subl (%rdi), %ebp
leal 0x1(%rbp), %r13d
movswl 0x14(%rdi), %edi
addl $0x10, %ebp
testl %r13d, %r13d
cmovnsl %r13d, %ebp
sarl $0x4, %ebp
cmpl %edi, %ebp
jl 0x637b8
movq %rdx, %r13
subq %rax, %r13
cmovlq %rdx, %rax
leaq 0xf(%rax), %rbp
testq %rax, %rax
cmovnsq %rax, %rbp
sarq $0x4, %rbp
cmpq $0x2, %rbp
movl $0x1, %eax
cmovlq %rax, %rbp
movq %r13, %rax
negq %rax
cmovsq %r13, %rax
xorl %edx, %edx
divq %rbp
cmpq %rax, -0x28(%rsp)
jle 0x63798
movq %rax, -0x28(%rsp)
movq %r10, -0x20(%rsp)
jmp 0x637b5
jne 0x637b5
movq -0x20(%rsp), %rdx
movq %rdx, %rax
shlq $0x5, %rax
cmpw %di, 0x14(%r15,%rax)
cmovgq %r10, %rdx
movq %rdx, -0x20(%rsp)
incq %rsi
addq %r9, %r14
cmpq %rcx, %r14
jl 0x636c9
movq -0x20(%rsp), %rdx
cmpq $-0x1, %rdx
je 0x6380a
movq -0x10(%rsp), %rax
movq 0x58(%rax), %rax
shlq $0x5, %rdx
movslq 0x4(%rax,%rdx), %rcx
incq %rcx
movq 0x60(%rsp), %r9
movq %rcx, (%r9)
movslq 0xc(%rax,%rdx), %rax
incq %rax
movq 0x70(%rsp), %rcx
movq %rax, (%rcx)
movq 0x78(%rsp), %rax
movq $0x0, (%rax)
jmp 0x6381a
movq 0x60(%rsp), %r9
movq %rcx, (%r9)
movq 0x70(%rsp), %rax
movq %r8, (%rax)
movq 0x58(%rsp), %rsi
movq 0x50(%rsp), %rdi
movq (%rdi), %rax
movq 0x48(%rsp), %r10
movq (%r10), %rcx
cmpq $-0x1, %rax
movq -0x18(%rsp), %r8
jne 0x63874
movq %rcx, (%rdi)
movq %rcx, %rax
cmpq %rbx, %rcx
jge 0x63874
shlq $0x4, %rax
addq %r8, %rax
addq $0x8, %rax
movl (%rax), %edx
cmpq %rdx, (%rsi)
jg 0x6386e
cmpq %rdx, (%r9)
jl 0x6386e
incq %rcx
movq %rcx, (%rdi)
addq $0x10, %rax
cmpq %rcx, %rbx
jne 0x63850
movq %rbx, %rcx
movq %rcx, %rax
movq (%r10), %rcx
cmpq $-0x1, %rcx
jne 0x638bf
movq %rax, (%r10)
testq %rax, %rax
js 0x638b6
movq %rax, %rcx
shlq $0x4, %rcx
addq %r8, %rcx
addq $0x8, %rcx
movl (%rcx), %edx
cmpq %rdx, (%rsi)
jg 0x638b6
cmpq %rdx, (%r9)
jl 0x638b6
leaq -0x1(%rax), %rdx
movq %rdx, (%r10)
addq $-0x10, %rcx
testq %rax, %rax
movq %rdx, %rax
jg 0x63890
movq $-0x1, %rax
incq %rax
movq %rax, (%r10)
movq (%rdi), %rax
cmpq %rbx, %rax
jge 0x638f9
negq %rbx
leaq 0x1(%rax), %rcx
shlq $0x4, %rax
addq %r8, %rax
addq $0x8, %rax
movl (%rax), %edx
cmpq %rdx, (%rsi)
jg 0x638f9
cmpq %rdx, (%r9)
jl 0x638f9
movq %rcx, (%rdi)
leaq (%rbx,%rcx), %rdx
incq %rdx
incq %rcx
addq $0x10, %rax
cmpq $0x1, %rdx
jne 0x638d6
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpq $-0x1, %r10
cmovneq %r10, %rsi
cmpq $-0x1, %rdx
cmovneq %rdx, %rsi
jmp 0x6364b