// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rcx, %r15
movq 0x58(%rdx), %rax
shlq $0x5, %r15
movslq (%rax,%r15), %r10
movslq 0x4(%rax,%r15), %r13
incq %r13
movq %r13, %rcx
subq %r10, %rcx
cmpq $0x200, %rcx            # imm = 0x200
jl 0x38099
movq %r8, %r11
movslq 0x8(%rax,%r15), %r8
movslq 0xc(%rax,%r15), %r12
incq %r12
movq %r12, %rcx
subq %r8, %rcx
cmpq $0x200, %rcx            # imm = 0x200
jl 0x38099
movq %rdx, 0x28(%rsp)
movq 0xd0(%rsp), %rbp
movq 0xc8(%rsp), %r14
movq 0xc0(%rsp), %rcx
movq 0x8(%rsi), %rdx
movq %rdx, 0x38(%rsp)
addq %r15, %rax
movswq 0x16(%rax), %rbx
subq $0x70, %rsp
movq %rbx, 0x50(%rsp)
movq 0x158(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x150(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0x148(%rsp), %rax
movq %rax, 0x38(%rsp)
movq %rbp, 0x30(%rsp)
movq %r14, 0x28(%rsp)
movq %r10, %r14
movq %rcx, 0x20(%rsp)
movq 0x128(%rsp), %rax
movq %rax, 0x18(%rsp)
movq 0x120(%rsp), %rax
movq %rax, 0x10(%rsp)
movq %r9, 0xd8(%rsp)
movq %r9, 0x8(%rsp)
andq $0x0, 0x60(%rsp)
movq %r11, 0xd0(%rsp)
movq %r11, (%rsp)
movq %rdi, 0xc8(%rsp)
movq %r10, %rdx
movq %r13, %rcx
movq %r8, %rbp
movq %r12, %r9
movq %xmm0, 0xe0(%rsp)
movq %rsi, 0xa0(%rsp)
callq 0x374c9
movq 0xa0(%rsp), %r10
addq $0x70, %rsp
testq %rax, %rax
je 0x38090
movq 0x38(%rsp), %rsi
shlq $0x4, %rsi
addq (%r10), %rsi
orq $-0x1, 0x1c(%rsp)
andl $0x0, 0x10(%rsp)
movzwl %bx, %r11d
movq 0xd8(%rsp), %rcx
movl %ecx, 0x14(%rsp)
testl %r11d, %r11d
je 0x37eaf
cmpl $0x2, %r11d
je 0x37f22
cmpl $0x1, %r11d
jne 0x37f6f
andl $0x0, 0xc(%rsp)
movl %eax, 0x18(%rsp)
movl 0x8(%rsi), %edx
movl %edx, 0x10(%rsp)
movl 0x4(%rsi), %ecx
movl %ecx, 0x1c(%rsp)
cmpq %r14, %rdx
jne 0x37e90
cmpq %rbp, %rcx
je 0x37f65
leaq 0x1ad4f6(%rip), %rdi    # 0x1e538d
leaq 0x1ab805(%rip), %rsi    # 0x1e36a3
leaq 0x1ad51a(%rip), %rcx    # 0x1e53bf
movl $0x4316, %edx           # imm = 0x4316
callq 0x2110
andl $0x0, 0xc(%rsp)
leaq -0x1(%rax), %rcx
movl %ecx, 0x18(%rsp)
movl 0x8(%rsi), %edi
movl %edi, 0x10(%rsp)
movl 0x4(%rsi), %edx
movl %edx, 0x1c(%rsp)
movl %ecx, %r8d
shlq $0x4, %r8
movl 0x8(%rsi,%r8), %r9d
movl %r9d, 0x14(%rsp)
movl 0x4(%rsi,%r8), %r8d
movl %r8d, 0x20(%rsp)
cmpq %r14, %rdi
jne 0x380e6
cmpq %rbp, %rdx
jne 0x380e6
shlq $0x4, %rcx
movl 0x8(%rsi,%rcx), %edx
cmpq %r13, %rdx
jne 0x380a8
addq %rsi, %rcx
movl 0x4(%rcx), %ecx
cmpq %r12, %rcx
jne 0x380a8
cmpq $0x3, %rax
jge 0x37f6f
jmp 0x38090
orl $-0x1, 0xc(%rsp)
leaq -0x1(%rax), %rcx
movl %ecx, 0x18(%rsp)
movl %ecx, %edx
shlq $0x4, %rdx
movl 0x8(%rsi,%rdx), %edi
movl %edi, 0x14(%rsp)
movl 0x4(%rsi,%rdx), %edx
movl %edx, 0x20(%rsp)
shlq $0x4, %rcx
movl 0x8(%rsi,%rcx), %edx
cmpq %r13, %rdx
jne 0x380c7
addq %rsi, %rcx
movl 0x4(%rcx), %ecx
cmpq %r12, %rcx
jne 0x380c7
cmpq $0x2, %rax
jl 0x38090
movq 0x28(%rsp), %r14
movq 0x48(%r14), %rbx
subq $0x10, %rsp
leaq 0x1c(%rsp), %rcx
movq 0x68(%rsp), %rdi
movq %rax, %rdx
movq 0x70(%rsp), %r8
movq 0x78(%rsp), %r9
movq 0x80(%rsp), %xmm0
pushq 0xf0(%rsp)
pushq 0xf0(%rsp)
pushq %r14
pushq 0xf8(%rsp)
pushq 0xf8(%rsp)
pushq 0xf8(%rsp)
pushq 0xf8(%rsp)
pushq 0xf8(%rsp)
movl %r11d, %ebp
callq 0x36a54
movq 0x80(%rsp), %r10
addq $0x50, %rsp
movq 0x48(%r14), %rcx
incq %rbx
cmpq %rbx, %rcx
jne 0x38090
movl %ebp, %r8d
movq 0x28(%rsp), %rax
movq 0x58(%rax), %rax
shlq $0x5, %rcx
cmpw $0x7fff, -0xc(%rax,%rcx) # imm = 0x7FFF
jne 0x3801d
leaq (%rax,%rcx), %rdx
cmpl $0x0, -0x4(%rdx)
jne 0x3801d
cmpw $0x0, -0xe(%rdx)
js 0x38090
addq %rax, %rcx
addq $-0x20, %rcx
testl %r8d, %r8d
sete %dl
movdqu (%rax,%r15), %xmm0
movdqu (%rcx), %xmm1
pcmpeqd %xmm0, %xmm1
movmskps %xmm1, %esi
xorl $0xf, %esi
sete %sil
cmpl $0x1, %r8d
sete %dil
movaps %xmm1, 0x40(%rsp)
cmpl $0x2, %r8d
sete %r8b
andb 0x44(%rsp), %r8b
testb %r8b, 0x4c(%rsp)
jne 0x38074
andb 0x40(%rsp), %dil
andb 0x48(%rsp), %dil
jne 0x38074
andb %dl, %sil
je 0x38090
addq %r15, %rax
movdqu (%rcx), %xmm0
movups 0x10(%rcx), %xmm1
movups %xmm1, 0x10(%rax)
movdqu %xmm0, (%rax)
movq 0x28(%rsp), %rax
decq 0x48(%rax)
movq 0x38(%rsp), %rax
movq %rax, 0x8(%r10)
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1ad3df(%rip), %rdi    # 0x1e548e
leaq 0x1ab5ed(%rip), %rsi    # 0x1e36a3
leaq 0x1ad302(%rip), %rcx    # 0x1e53bf
movl $0x430f, %edx           # imm = 0x430F
callq 0x2110
leaq 0x1ad3c0(%rip), %rdi    # 0x1e548e
leaq 0x1ab5ce(%rip), %rsi    # 0x1e36a3
leaq 0x1ad2e3(%rip), %rcx    # 0x1e53bf
movl $0x431d, %edx           # imm = 0x431D
callq 0x2110
leaq 0x1ad2a0(%rip), %rdi    # 0x1e538d
leaq 0x1ab5af(%rip), %rsi    # 0x1e36a3
leaq 0x1ad2c4(%rip), %rcx    # 0x1e53bf
movl $0x430e, %edx           # imm = 0x430E
callq 0x2110