// File: chhylp123[P]hifiasm/Correct.cpp
// Function: extract_sub_werr(bit_extz_t*, long, long, long, long, long, long, long, long, long, long, long, rtrace_iter*)
int64_t extract_sub_werr(bit_extz_t *ez, int64_t csi, int64_t cei, int64_t cps, int64_t cpe, int64_t cts, int64_t cte, 
int64_t tar_ps, int64_t tar_pe, int64_t tar_ts, int64_t tar_te, int64_t spec_toff, rtrace_iter *idx)
{
    if(idx->toff >= tar_pe && idx->qoff >= tar_te) {
        idx->coff = cei-1;
        idx->toff = cpe;
        idx->qoff = cte;
        idx->cerr = 0;
    }
    if(!(is_align(*ez))) return INT32_MAX;
    if(!(ez->cigar.n)) return (((double)(tar_te-spec_toff))/((double)(tar_te-tar_ts)))*ez->err;

    int64_t ci = idx->coff, pi = idx->toff, ti = idx->qoff, err = idx->cerr;
    int64_t t[2], ci0, pi0, ti0, err0, re = INT32_MAX, wts, wte, ps1, pe1;
    uint16_t c, sset = 0, eset = 0, ff[2]; uint32_t cl;
    while (ci >= csi) {
        ci0 = ci; pi0 = pi; ti0 = ti; err0 = err;
        ci = pop_trace_back(&(ez->cigar), ci, &c, &cl);
        wte = ti; 
        if(c <= 1) {
            pi-=cl; ti-=cl;
        } else if(c == 2) {///more p
            pi-=cl;
        } else if(c == 3) {
            ti-=cl;
        }
        wts = ti; ff[0] = ff[1] = 0;
        t[0] = wts; t[1] = wte;
        // if(spec_toff == 118374) {
        //     fprintf(stderr, "+[M::%s::ci->%ld::cl->%u::c->%u] spec_toff::%ld, t::[%ld, %ld), p::[%ld, %ld), err0::%ld\n", 
        //     __func__, ci, cl, c, spec_toff, ti, ti0, pi, pi0, err0);
        // }

        if(wte < tar_ts) {///not we <= ps
            if(c != 0) err += cl;
            break;
        }
        if(wts > tar_te) {///not ws >= pe
            if(c != 0) err += cl;
            continue;
        }

        if(!eset) {
            if((tar_te>wts) && (tar_te<=wte)) {
                assert(c != 2);
                if(c <= 1) {
                    pe1 = pi + (tar_te - wts); 
                    if(pe1 == tar_pe) {
                        if(c == 1) err = tar_te - wts;
                        else err = 0;
                        eset = 1; 
                    }
                } else if(c == 3) {///more t
                    pe1 = pi;
                    if(pe1 == tar_pe) {
                        err = tar_te - wts;
                        eset = 1; 
                    }
                }
            }

            if((c == 2) && (tar_te>=wts) && (tar_te<=wte)) {///more p
                if(tar_pe >= pi && tar_pe < pi + cl) {
                    err = tar_pe - pi;
                    eset = 1; 
                }
            }
            if(eset) {
                ff[0] = 1; t[1] = tar_te;
            }
        }


        if(!sset) {
            if((tar_ts>=wts) && (tar_ts<wte)) {
                assert(c != 2);
                if(c <= 1) {
                    ps1 = pi + (tar_ts - wts); 
                    if(ps1 == tar_ps) {
                        if(c == 1) err += (wte - tar_ts); 
                        sset = 1; 
                    }
                } else if(c == 3) {///more t
                    ps1 = pi; 
                    if(ps1 == tar_ps) {
                        err += (wte - tar_ts);
                        sset = 1; 
                    }
                }
            } 

            if((c == 2) && (tar_ts>=wts) && (tar_ts<=wte)) {///more p
                if(tar_ps >= pi && tar_ps < pi + cl) {
                    err += (pi + cl - tar_ps);
                    sset = 1; 
                }
            }
            if(sset) {
                ff[1] = 1; t[0] = tar_ts;
            }
        }

        // if(spec_toff == 118374) {
        //     fprintf(stderr, "-[M::%s::ci->%ld::cl->%u::c->%u] spec_toff::%ld, t::[%ld, %ld), p::[%ld, %ld), err0::%ld\n", 
        //     __func__, ci, cl, c, spec_toff, ti, ti0, pi, pi0, err0);
        // }
        if(spec_toff > t[1]) break;

        if((spec_toff >= t[0] && spec_toff < t[1]) || (spec_toff == t[0] && spec_toff == t[1])) {
            re = err + (((!ff[1]) && (!ff[0]) && (c!=0))?cl:0);
            if(c == 1 || c == 3) re -= (spec_toff - t[0]);
            idx->coff = ci0;
            idx->toff = pi0;
            idx->qoff = ti0;
            idx->cerr = err0;
            // return re;
        }
        if(ff[1]) break;
        if(ff[0]) continue;
        if(c!=0) err += cl;
    }
    return re;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xe0, %rsp
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, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
movq %r8, -0x30(%rbp)
movq %r9, -0x38(%rbp)
movq 0x40(%rbp), %rax
movq 0x80(%rax), %rax
cmpq 0x20(%rbp), %rax
jl 0x91bc8
movq 0x40(%rbp), %rax
movq 0x70(%rax), %rax
cmpq 0x30(%rbp), %rax
jl 0x91bc8
movq -0x20(%rbp), %rcx
subq $0x1, %rcx
movq 0x40(%rbp), %rax
movq %rcx, 0x88(%rax)
movq -0x30(%rbp), %rcx
movq 0x40(%rbp), %rax
movq %rcx, 0x80(%rax)
movq 0x10(%rbp), %rcx
movq 0x40(%rbp), %rax
movq %rcx, 0x70(%rax)
movq 0x40(%rbp), %rax
movq $0x0, 0x68(%rax)
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x28(%rcx), %eax
jle 0x91be5
movq $0x7fffffff, -0x8(%rbp) # imm = 0x7FFFFFFF
jmp 0x92239
movq -0x10(%rbp), %rax
cmpq $0x0, 0xa8(%rax)
jne 0x91c2c
movq 0x30(%rbp), %rax
subq 0x38(%rbp), %rax
cvtsi2sd %rax, %xmm0
movq 0x30(%rbp), %rax
subq 0x28(%rbp), %rax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
movq -0x10(%rbp), %rax
cvtsi2sdl 0x2c(%rax), %xmm1
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movq %rax, -0x8(%rbp)
jmp 0x92239
movq 0x40(%rbp), %rax
movq 0x88(%rax), %rax
movq %rax, -0x40(%rbp)
movq 0x40(%rbp), %rax
movq 0x80(%rax), %rax
movq %rax, -0x48(%rbp)
movq 0x40(%rbp), %rax
movq 0x70(%rax), %rax
movq %rax, -0x50(%rbp)
movq 0x40(%rbp), %rax
movq 0x68(%rax), %rax
movq %rax, -0x58(%rbp)
movq $0x7fffffff, -0x98(%rbp) # imm = 0x7FFFFFFF
movw $0x0, -0xbc(%rbp)
movw $0x0, -0xbe(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x18(%rbp), %rax
jl 0x9222e
movq -0x40(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rdi
addq $0xa8, %rdi
movq -0x40(%rbp), %rax
movl %eax, %esi
leaq -0xba(%rbp), %rdx
leaq -0xc8(%rbp), %rcx
callq 0xc1f00
cltq
movq %rax, -0x40(%rbp)
movq -0x50(%rbp), %rax
movq %rax, -0xa8(%rbp)
movzwl -0xba(%rbp), %eax
cmpl $0x1, %eax
jg 0x91d1c
movl -0xc8(%rbp), %eax
movl %eax, %ecx
movq -0x48(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x48(%rbp)
movl -0xc8(%rbp), %eax
movl %eax, %ecx
movq -0x50(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x50(%rbp)
jmp 0x91d60
movzwl -0xba(%rbp), %eax
cmpl $0x2, %eax
jne 0x91d3d
movl -0xc8(%rbp), %eax
movl %eax, %ecx
movq -0x48(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x48(%rbp)
jmp 0x91d5e
movzwl -0xba(%rbp), %eax
cmpl $0x3, %eax
jne 0x91d5c
movl -0xc8(%rbp), %eax
movl %eax, %ecx
movq -0x50(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x50(%rbp)
jmp 0x91d5e
jmp 0x91d60
movq -0x50(%rbp), %rax
movq %rax, -0xa0(%rbp)
movw $0x0, -0xc0(%rbp)
movw $0x0, -0xc2(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0xa8(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0xa8(%rbp), %rax
cmpq 0x28(%rbp), %rax
jge 0x91dbf
movzwl -0xba(%rbp), %eax
cmpl $0x0, %eax
je 0x91dba
movl -0xc8(%rbp), %eax
addq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x9222e
movq -0xa0(%rbp), %rax
cmpq 0x30(%rbp), %rax
jle 0x91deb
movzwl -0xba(%rbp), %eax
cmpl $0x0, %eax
je 0x91de6
movl -0xc8(%rbp), %eax
addq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x91c7f
cmpw $0x0, -0xbe(%rbp)
jne 0x91f66
movq 0x30(%rbp), %rax
cmpq -0xa0(%rbp), %rax
jle 0x91eec
movq 0x30(%rbp), %rax
cmpq -0xa8(%rbp), %rax
jg 0x91eec
movzwl -0xba(%rbp), %eax
cmpl $0x2, %eax
je 0x91e29
jmp 0x91e48
leaq 0x2f3d6f(%rip), %rdi    # 0x385b9f
leaq 0x2f04e4(%rip), %rsi    # 0x38231b
movl $0x5d48, %edx           # imm = 0x5D48
leaq 0x2f3e8c(%rip), %rcx    # 0x385ccf
callq 0x2130
movzwl -0xba(%rbp), %eax
cmpl $0x1, %eax
jg 0x91eaa
movq -0x48(%rbp), %rax
movq 0x30(%rbp), %rcx
subq -0xa0(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
cmpq 0x20(%rbp), %rax
jne 0x91ea8
movzwl -0xba(%rbp), %eax
cmpl $0x1, %eax
jne 0x91e97
movq 0x30(%rbp), %rax
subq -0xa0(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x91e9f
movq $0x0, -0x58(%rbp)
movw $0x1, -0xbe(%rbp)
jmp 0x91eea
movzwl -0xba(%rbp), %eax
cmpl $0x3, %eax
jne 0x91ee8
movq -0x48(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
cmpq 0x20(%rbp), %rax
jne 0x91ee6
movq 0x30(%rbp), %rax
subq -0xa0(%rbp), %rax
movq %rax, -0x58(%rbp)
movw $0x1, -0xbe(%rbp)
jmp 0x91ee8
jmp 0x91eea
jmp 0x91eec
movzwl -0xba(%rbp), %eax
cmpl $0x2, %eax
jne 0x91f49
movq 0x30(%rbp), %rax
cmpq -0xa0(%rbp), %rax
jl 0x91f49
movq 0x30(%rbp), %rax
cmpq -0xa8(%rbp), %rax
jg 0x91f49
movq 0x20(%rbp), %rax
cmpq -0x48(%rbp), %rax
jl 0x91f47
movq 0x20(%rbp), %rax
movq -0x48(%rbp), %rcx
movl -0xc8(%rbp), %edx
addq %rdx, %rcx
cmpq %rcx, %rax
jge 0x91f47
movq 0x20(%rbp), %rax
subq -0x48(%rbp), %rax
movq %rax, -0x58(%rbp)
movw $0x1, -0xbe(%rbp)
jmp 0x91f49
cmpw $0x0, -0xbe(%rbp)
je 0x91f64
movw $0x1, -0xc2(%rbp)
movq 0x30(%rbp), %rax
movq %rax, -0x68(%rbp)
jmp 0x91f66
cmpw $0x0, -0xbc(%rbp)
jne 0x920ec
movq 0x28(%rbp), %rax
cmpq -0xa0(%rbp), %rax
jl 0x92065
movq 0x28(%rbp), %rax
cmpq -0xa8(%rbp), %rax
jge 0x92065
movzwl -0xba(%rbp), %eax
cmpl $0x2, %eax
je 0x91fa4
jmp 0x91fc3
leaq 0x2f3bf4(%rip), %rdi    # 0x385b9f
leaq 0x2f0369(%rip), %rsi    # 0x38231b
movl $0x5d67, %edx           # imm = 0x5D67
leaq 0x2f3d11(%rip), %rcx    # 0x385ccf
callq 0x2130
movzwl -0xba(%rbp), %eax
cmpl $0x1, %eax
jg 0x9201f
movq -0x48(%rbp), %rax
movq 0x28(%rbp), %rcx
subq -0xa0(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
cmpq 0x18(%rbp), %rax
jne 0x9201d
movzwl -0xba(%rbp), %eax
cmpl $0x1, %eax
jne 0x92014
movq -0xa8(%rbp), %rax
subq 0x28(%rbp), %rax
addq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
movw $0x1, -0xbc(%rbp)
jmp 0x92063
movzwl -0xba(%rbp), %eax
cmpl $0x3, %eax
jne 0x92061
movq -0x48(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
cmpq 0x18(%rbp), %rax
jne 0x9205f
movq -0xa8(%rbp), %rax
subq 0x28(%rbp), %rax
addq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
movw $0x1, -0xbc(%rbp)
jmp 0x92061
jmp 0x92063
jmp 0x92065
movzwl -0xba(%rbp), %eax
cmpl $0x2, %eax
jne 0x920cf
movq 0x28(%rbp), %rax
cmpq -0xa0(%rbp), %rax
jl 0x920cf
movq 0x28(%rbp), %rax
cmpq -0xa8(%rbp), %rax
jg 0x920cf
movq 0x18(%rbp), %rax
cmpq -0x48(%rbp), %rax
jl 0x920cd
movq 0x18(%rbp), %rax
movq -0x48(%rbp), %rcx
movl -0xc8(%rbp), %edx
addq %rdx, %rcx
cmpq %rcx, %rax
jge 0x920cd
movq -0x48(%rbp), %rax
movl -0xc8(%rbp), %ecx
addq %rcx, %rax
subq 0x18(%rbp), %rax
addq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
movw $0x1, -0xbc(%rbp)
jmp 0x920cf
cmpw $0x0, -0xbc(%rbp)
je 0x920ea
movw $0x1, -0xc0(%rbp)
movq 0x28(%rbp), %rax
movq %rax, -0x70(%rbp)
jmp 0x920ec
movq 0x38(%rbp), %rax
cmpq -0x68(%rbp), %rax
jle 0x920fb
jmp 0x9222e
movq 0x38(%rbp), %rax
cmpq -0x70(%rbp), %rax
jl 0x9210f
movq 0x38(%rbp), %rax
cmpq -0x68(%rbp), %rax
jl 0x9212b
movq 0x38(%rbp), %rax
cmpq -0x70(%rbp), %rax
jne 0x921f4
movq 0x38(%rbp), %rax
cmpq -0x68(%rbp), %rax
jne 0x921f4
movq -0x58(%rbp), %rax
movq %rax, -0xd0(%rbp)
cmpw $0x0, -0xc0(%rbp)
jne 0x92164
cmpw $0x0, -0xc2(%rbp)
jne 0x92164
movzwl -0xba(%rbp), %eax
cmpl $0x0, %eax
je 0x92164
movl -0xc8(%rbp), %eax
movl %eax, -0xd4(%rbp)
jmp 0x9216e
xorl %eax, %eax
movl %eax, -0xd4(%rbp)
jmp 0x9216e
movq -0xd0(%rbp), %rax
movl -0xd4(%rbp), %ecx
movl %ecx, %ecx
addq %rcx, %rax
movq %rax, -0x98(%rbp)
movzwl -0xba(%rbp), %eax
cmpl $0x1, %eax
je 0x9219f
movzwl -0xba(%rbp), %eax
cmpl $0x3, %eax
jne 0x921b8
movq 0x38(%rbp), %rcx
subq -0x70(%rbp), %rcx
movq -0x98(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x98(%rbp)
movq -0x78(%rbp), %rcx
movq 0x40(%rbp), %rax
movq %rcx, 0x88(%rax)
movq -0x80(%rbp), %rcx
movq 0x40(%rbp), %rax
movq %rcx, 0x80(%rax)
movq -0x88(%rbp), %rcx
movq 0x40(%rbp), %rax
movq %rcx, 0x70(%rax)
movq -0x90(%rbp), %rcx
movq 0x40(%rbp), %rax
movq %rcx, 0x68(%rax)
cmpw $0x0, -0xc0(%rbp)
je 0x92200
jmp 0x9222e
cmpw $0x0, -0xc2(%rbp)
je 0x9220f
jmp 0x91c7f
movzwl -0xba(%rbp), %eax
cmpl $0x0, %eax
je 0x92229
movl -0xc8(%rbp), %eax
addq -0x58(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x91c7f
movq -0x98(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xe0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)