// File: chhylp123[P]hifiasm/Correct.cpp
// Function: rechain_aln(overlap_region*, Candidates_list*, overlap_region*, long, long, ul_idx_t const*, hpc_t*, All_reads*, char*, UC_Read*, bit_extz_t*, double, long, long, long, long)
void rechain_aln(overlap_region *z, Candidates_list *cl, overlap_region *aux_o, int64_t aux_i, int64_t wl, 
const ul_idx_t *uref, hpc_t *hpc_g, All_reads *rref, char* qstr, UC_Read *tu, bit_extz_t *exz, double e_rate, 
int64_t ql, int64_t tl, int64_t h_khit, int64_t rid)
{
    int64_t rcn = cl->length, ch_n, qs, qe, ts, te, mode, an0, an, todo; 
    k_mer_hit *ch_a; ul_ov_t idx; uint8_t q[2], t[2];
    ///[qs, qe) && [ts, te)
    qs = aux_o->w_list.a[aux_i].x_start; qe = aux_o->w_list.a[aux_i].x_end+1;
    ts = aux_o->w_list.a[aux_i].y_start; te = aux_o->w_list.a[aux_i].y_end+1;
    if(qe - qs < FORCE_SIN_L || te - ts < FORCE_SIN_L) return;
    mode = aux_o->w_list.a[aux_i].error_threshold;
    ch_n = gen_win_chain(z, cl, qs, qe, ts, te, wl, uref, hpc_g, rref, qstr, tu, exz, ql, tl, e_rate, h_khit, mode, rid, 0);
    ch_a = cl->list + rcn;
    if(ch_n) {
        idx.ts = idx.te = (uint32_t)-1; idx.qs = 0; idx.qe = ql; todo = 1;
        if(mode == 0) {//global
            idx.qn = 0; idx.tn = ch_n - 1;
            idx.qs = ch_a[idx.qn].self_offset;
            idx.ts = ch_a[idx.qn].offset;
            idx.qe = ch_a[idx.tn].self_offset;
            idx.te = ch_a[idx.tn].offset;
            assert(ch_a[0].self_offset == qs && ch_a[0].offset == ts);
            assert(ch_a[ch_n-1].self_offset == qe && ch_a[ch_n-1].offset == te);
            if(ch_n <= 2) todo = 0;
        } else if(mode == 1) {//forward ext
            idx.qn = 0; idx.tn = ch_n;
            idx.qs = ch_a[idx.qn].self_offset;
            idx.ts = ch_a[idx.qn].offset;
            idx.qe = ql; 
            assert(ch_a[0].self_offset == qs && ch_a[0].offset == ts);
            if(ch_n <= 1) todo = 0;
        } else if(mode == 2) {///backward ext
            idx.qn = (uint32_t)-1; idx.tn = ch_n-1;
            idx.qs = 0; 
            idx.qe = ch_a[idx.tn].self_offset;
            idx.te = ch_a[idx.tn].offset;
            assert(ch_a[ch_n-1].self_offset == qe && ch_a[ch_n-1].offset == te);
            if(ch_n <= 1) todo = 0;
        }
        if(todo) {
            an0 = aux_o->w_list.n;
            // if(z->x_id == 29033 && z->y_id == 21307) {
            //     fprintf(stderr, "[M::%s]\tan0::%ld\tq::[%u,\t%u)\tt::[%u,\t%u)\tlw::%u\trw::%u\n", __func__, an0,
            //     idx.qs, idx.qe, idx.ts, idx.te, idx.qn, idx.tn);
            // }
            ovlp_base_aln(z, ch_a, ch_n, &idx, wl, uref, hpc_g, rref, qstr, tu, exz, aux_o, e_rate, ql, tl, (uint64_t)-1);
            an = aux_o->w_list.n; q[0] = q[1] = t[0] = t[1] = 0; todo = 0;
            // if(z->x_id == 29033 && z->y_id == 21307) {
            //     fprintf(stderr, "[M::%s]\tan::%ld\n", __func__, an);
            // }
            // fprintf(stderr, "[M::%s::] awn0::%ld, awn::%lu\n", __func__, an0, an);
            ///old unaligned window could be replaced by the new aligned window
            if((an == (an0 + 1)) && (!(is_ualn_win(aux_o->w_list.a[an-1])))) {
                if(aux_o->w_list.a[aux_i].x_start == aux_o->w_list.a[an-1].x_start) q[0] = 1;
                if(aux_o->w_list.a[aux_i].x_end == aux_o->w_list.a[an-1].x_end) q[1] = 1;
                if(aux_o->w_list.a[aux_i].y_start == aux_o->w_list.a[an-1].y_start) t[0] = 1;
                if(aux_o->w_list.a[aux_i].y_end == aux_o->w_list.a[an-1].y_end) t[1] = 1;
                if((mode == 0) && q[0] && q[1] && t[0] && t[1]) todo = 1;
                if((mode == 1) && q[0] && t[0]) todo = 1;
                if((mode == 2) && q[1] && t[1]) todo = 1;
                if(todo) {
                    aux_o->w_list.a[aux_i] = aux_o->w_list.a[an-1]; aux_o->w_list.n--;
                }
            }
            // if(an > an0) {///should always > 0 as there are unmapped windows
            // }
            // aux_o->w_list.n = an0;
        }
    }
    cl->length = rcn;///must reset!!!!
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
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 -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movslq (%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
addl $0x1, %eax
cltq
movq %rax, -0x80(%rbp)
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movslq 0x8(%rax), %rax
movq %rax, -0x88(%rbp)
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
addl $0x1, %eax
cltq
movq %rax, -0x90(%rbp)
movq -0x80(%rbp), %rax
subq -0x78(%rbp), %rax
cmpq $0x200, %rax            # imm = 0x200
jl 0x66860
movq -0x90(%rbp), %rax
subq -0x88(%rbp), %rax
cmpq $0x200, %rax            # imm = 0x200
jge 0x66865
jmp 0x67074
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movswq 0x16(%rax), %rax
movq %rax, -0x98(%rbp)
movq -0x30(%rbp), %rdi
movq -0x38(%rbp), %rsi
movq -0x78(%rbp), %rdx
movq -0x80(%rbp), %rcx
movq -0x88(%rbp), %r8
movq -0x90(%rbp), %r9
movq -0x50(%rbp), %rax
movq %rax, -0x100(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq 0x10(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq 0x18(%rbp), %rax
movq %rax, -0xe8(%rbp)
movq 0x20(%rbp), %r13
movq 0x28(%rbp), %r12
movq 0x30(%rbp), %r15
movq 0x38(%rbp), %r14
movq 0x40(%rbp), %rbx
movsd -0x60(%rbp), %xmm0
movq 0x48(%rbp), %r11
movq -0x98(%rbp), %r10
movq 0x50(%rbp), %rax
movq %rax, -0xe0(%rbp)
xorl %eax, %eax
movq -0x100(%rbp), %rax
movq %rax, (%rsp)
movq -0xf8(%rbp), %rax
movq %rax, 0x8(%rsp)
movq -0xf0(%rbp), %rax
movq %rax, 0x10(%rsp)
movq -0xe8(%rbp), %rax
movq %rax, 0x18(%rsp)
movq -0xe0(%rbp), %rax
movq %r13, 0x20(%rsp)
movq %r12, 0x28(%rsp)
movq %r15, 0x30(%rsp)
movq %r14, 0x38(%rsp)
movq %rbx, 0x40(%rsp)
movq %r11, 0x48(%rsp)
movq %r10, 0x50(%rsp)
movq %rax, 0x58(%rsp)
movq $0x0, 0x60(%rsp)
callq 0x65560
movq %rax, -0x70(%rbp)
movq -0x38(%rbp), %rax
movq (%rax), %rax
movq -0x68(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0xb8(%rbp)
cmpq $0x0, -0x70(%rbp)
je 0x67068
movl $0xffffffff, -0xc0(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0xc4(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0xd0(%rbp)
movq 0x38(%rbp), %rax
movl %eax, -0xcc(%rbp)
movq $0x1, -0xb0(%rbp)
cmpq $0x0, -0x98(%rbp)
jne 0x66b57
movl $0x0, -0xd4(%rbp)
movq -0x70(%rbp), %rax
subq $0x1, %rax
movl %eax, -0xc8(%rbp)
movq -0xb8(%rbp), %rax
movl -0xd4(%rbp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movl %eax, -0xd0(%rbp)
movq -0xb8(%rbp), %rax
movl -0xd4(%rbp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, -0xc4(%rbp)
movq -0xb8(%rbp), %rax
movl -0xc8(%rbp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movl %eax, -0xcc(%rbp)
movq -0xb8(%rbp), %rax
movl -0xc8(%rbp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, -0xc0(%rbp)
movq -0xb8(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, %ecx
xorl %eax, %eax
cmpq -0x78(%rbp), %rcx
movb %al, -0x101(%rbp)
jne 0x66a94
movq -0xb8(%rbp), %rax
movl 0x4(%rax), %eax
cmpq -0x88(%rbp), %rax
sete %al
movb %al, -0x101(%rbp)
movb -0x101(%rbp), %al
testb $0x1, %al
jne 0x66aa0
jmp 0x66aa2
jmp 0x66ac1
leaq 0x31d55c(%rip), %rdi    # 0x384005
leaq 0x31b86b(%rip), %rsi    # 0x38231b
movl $0x430e, %edx           # imm = 0x430E
leaq 0x31d57b(%rip), %rcx    # 0x384037
callq 0x2130
movq -0xb8(%rbp), %rax
movq -0x70(%rbp), %rcx
subq $0x1, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movl %eax, %ecx
xorl %eax, %eax
cmpq -0x80(%rbp), %rcx
movb %al, -0x102(%rbp)
jne 0x66b13
movq -0xb8(%rbp), %rax
movq -0x70(%rbp), %rcx
subq $0x1, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
cmpq -0x90(%rbp), %rax
sete %al
movb %al, -0x102(%rbp)
movb -0x102(%rbp), %al
testb $0x1, %al
jne 0x66b1f
jmp 0x66b21
jmp 0x66b40
leaq 0x31d5de(%rip), %rdi    # 0x384106
leaq 0x31b7ec(%rip), %rsi    # 0x38231b
movl $0x430f, %edx           # imm = 0x430F
leaq 0x31d4fc(%rip), %rcx    # 0x384037
callq 0x2130
cmpq $0x2, -0x70(%rbp)
jg 0x66b52
movq $0x0, -0xb0(%rbp)
jmp 0x66d36
cmpq $0x1, -0x98(%rbp)
jne 0x66c35
movl $0x0, -0xd4(%rbp)
movq -0x70(%rbp), %rax
movl %eax, -0xc8(%rbp)
movq -0xb8(%rbp), %rax
movl -0xd4(%rbp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movl %eax, -0xd0(%rbp)
movq -0xb8(%rbp), %rax
movl -0xd4(%rbp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, -0xc4(%rbp)
movq 0x38(%rbp), %rax
movl %eax, -0xcc(%rbp)
movq -0xb8(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, %ecx
xorl %eax, %eax
cmpq -0x78(%rbp), %rcx
movb %al, -0x103(%rbp)
jne 0x66bf1
movq -0xb8(%rbp), %rax
movl 0x4(%rax), %eax
cmpq -0x88(%rbp), %rax
sete %al
movb %al, -0x103(%rbp)
movb -0x103(%rbp), %al
testb $0x1, %al
jne 0x66bfd
jmp 0x66bff
jmp 0x66c1e
leaq 0x31d3ff(%rip), %rdi    # 0x384005
leaq 0x31b70e(%rip), %rsi    # 0x38231b
movl $0x4316, %edx           # imm = 0x4316
leaq 0x31d41e(%rip), %rcx    # 0x384037
callq 0x2130
cmpq $0x1, -0x70(%rbp)
jg 0x66c30
movq $0x0, -0xb0(%rbp)
jmp 0x66d34
cmpq $0x2, -0x98(%rbp)
jne 0x66d32
movl $0xffffffff, -0xd4(%rbp) # imm = 0xFFFFFFFF
movq -0x70(%rbp), %rax
subq $0x1, %rax
movl %eax, -0xc8(%rbp)
movl $0x0, -0xd0(%rbp)
movq -0xb8(%rbp), %rax
movl -0xc8(%rbp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movl %eax, -0xcc(%rbp)
movq -0xb8(%rbp), %rax
movl -0xc8(%rbp), %ecx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movl %eax, -0xc0(%rbp)
movq -0xb8(%rbp), %rax
movq -0x70(%rbp), %rcx
subq $0x1, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movl %eax, %ecx
xorl %eax, %eax
cmpq -0x80(%rbp), %rcx
movb %al, -0x104(%rbp)
jne 0x66cf1
movq -0xb8(%rbp), %rax
movq -0x70(%rbp), %rcx
subq $0x1, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
cmpq -0x90(%rbp), %rax
sete %al
movb %al, -0x104(%rbp)
movb -0x104(%rbp), %al
testb $0x1, %al
jne 0x66cfd
jmp 0x66cff
jmp 0x66d1e
leaq 0x31d400(%rip), %rdi    # 0x384106
leaq 0x31b60e(%rip), %rsi    # 0x38231b
movl $0x431d, %edx           # imm = 0x431D
leaq 0x31d31e(%rip), %rcx    # 0x384037
callq 0x2130
cmpq $0x1, -0x70(%rbp)
jg 0x66d30
movq $0x0, -0xb0(%rbp)
jmp 0x66d32
jmp 0x66d34
jmp 0x66d36
cmpq $0x0, -0xb0(%rbp)
je 0x67066
movq -0x40(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0xa0(%rbp)
movq -0x30(%rbp), %rdi
movq -0xb8(%rbp), %rsi
movq -0x70(%rbp), %rdx
movq -0x50(%rbp), %r8
movq -0x58(%rbp), %r9
movq 0x10(%rbp), %r13
movq 0x18(%rbp), %r12
movq 0x20(%rbp), %r15
movq 0x28(%rbp), %r14
movq 0x30(%rbp), %rbx
movq -0x40(%rbp), %r11
movsd -0x60(%rbp), %xmm0
movq 0x38(%rbp), %r10
movq 0x40(%rbp), %rax
leaq -0xd4(%rbp), %rcx
movq %r13, (%rsp)
movq %r12, 0x8(%rsp)
movq %r15, 0x10(%rsp)
movq %r14, 0x18(%rsp)
movq %rbx, 0x20(%rsp)
movq %r11, 0x28(%rsp)
movq %r10, 0x30(%rsp)
movq %rax, 0x38(%rsp)
movq $-0x1, 0x40(%rsp)
callq 0x64220
movq -0x40(%rbp), %rax
movq 0x48(%rax), %rax
movq %rax, -0xa8(%rbp)
movb $0x0, -0xd7(%rbp)
movb $0x0, -0xd8(%rbp)
movb $0x0, -0xd5(%rbp)
movb $0x0, -0xd6(%rbp)
movq $0x0, -0xb0(%rbp)
movq -0xa8(%rbp), %rax
movq -0xa0(%rbp), %rcx
addq $0x1, %rcx
cmpq %rcx, %rax
jne 0x67064
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0xa8(%rbp), %rcx
subq $0x1, %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movswl 0x14(%rax), %eax
cmpl $0x7fff, %eax           # imm = 0x7FFF
jne 0x66e88
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0xa8(%rbp), %rcx
subq $0x1, %rcx
shlq $0x5, %rcx
addq %rcx, %rax
cmpl $0x0, 0x1c(%rax)
jne 0x66e88
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0xa8(%rbp), %rcx
subq $0x1, %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movswl 0x12(%rax), %eax
cmpl $0x0, %eax
jl 0x67064
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl (%rax), %eax
movq -0x40(%rbp), %rcx
movq 0x58(%rcx), %rcx
movq -0xa8(%rbp), %rdx
subq $0x1, %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
cmpl (%rcx), %eax
jne 0x66ec2
movb $0x1, -0xd6(%rbp)
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0x4(%rax), %eax
movq -0x40(%rbp), %rcx
movq 0x58(%rcx), %rcx
movq -0xa8(%rbp), %rdx
subq $0x1, %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
cmpl 0x4(%rcx), %eax
jne 0x66efe
movb $0x1, -0xd5(%rbp)
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movq -0x40(%rbp), %rcx
movq 0x58(%rcx), %rcx
movq -0xa8(%rbp), %rdx
subq $0x1, %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
cmpl 0x8(%rcx), %eax
jne 0x66f3a
movb $0x1, -0xd8(%rbp)
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x48(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
movq -0x40(%rbp), %rcx
movq 0x58(%rcx), %rcx
movq -0xa8(%rbp), %rdx
subq $0x1, %rdx
shlq $0x5, %rdx
addq %rdx, %rcx
cmpl 0xc(%rcx), %eax
jne 0x66f76
movb $0x1, -0xd7(%rbp)
cmpq $0x0, -0x98(%rbp)
jne 0x66faf
cmpb $0x0, -0xd6(%rbp)
je 0x66faf
cmpb $0x0, -0xd5(%rbp)
je 0x66faf
cmpb $0x0, -0xd8(%rbp)
je 0x66faf
cmpb $0x0, -0xd7(%rbp)
je 0x66faf
movq $0x1, -0xb0(%rbp)
cmpq $0x1, -0x98(%rbp)
jne 0x66fd6
cmpb $0x0, -0xd6(%rbp)
je 0x66fd6
cmpb $0x0, -0xd8(%rbp)
je 0x66fd6
movq $0x1, -0xb0(%rbp)
cmpq $0x2, -0x98(%rbp)
jne 0x66ffd
cmpb $0x0, -0xd5(%rbp)
je 0x66ffd
cmpb $0x0, -0xd7(%rbp)
je 0x66ffd
movq $0x1, -0xb0(%rbp)
cmpq $0x0, -0xb0(%rbp)
je 0x67062
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rcx
movq -0xa8(%rbp), %rax
subq $0x1, %rax
shlq $0x5, %rax
addq %rax, %rcx
movq -0x40(%rbp), %rax
movq 0x58(%rax), %rax
movq -0x48(%rbp), %rdx
shlq $0x5, %rdx
addq %rdx, %rax
movq (%rcx), %rdx
movq %rdx, (%rax)
movq 0x8(%rcx), %rdx
movq %rdx, 0x8(%rax)
movq 0x10(%rcx), %rdx
movq %rdx, 0x10(%rax)
movq 0x18(%rcx), %rcx
movq %rcx, 0x18(%rax)
movq -0x40(%rbp), %rax
movq 0x48(%rax), %rcx
addq $-0x1, %rcx
movq %rcx, 0x48(%rax)
jmp 0x67064
jmp 0x67066
jmp 0x67068
movq -0x68(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nopw %cs:(%rax,%rax)