// File: chhylp123[P]hifiasm/ecovlp.cpp
// Function: extract_max_exact_sub(asg16_v*, long, long, long, long, long*, long*, long*, unsigned long*, unsigned long*, unsigned long*, unsigned long*)
uint32_t extract_max_exact_sub(asg16_v *in, int64_t xs0, int64_t xe0, int64_t ys0, int64_t ye0, int64_t *exk, int64_t *eyk, int64_t *eck, uint64_t *rxs, uint64_t *rxe, uint64_t *rys, uint64_t *rye)
{
    int64_t xk = *exk, yk = *eyk, ck = *eck, cn = in->n, ol, wx[2], wy[2], os, oe; uint16_t op, bq, bt; uint32_t cl, ovlp;
    *rxs = *rxe = *rys = *rye = 0;

    if((ck < 0) || (ck > cn)) {//(*ck) == cn is allowed
        ck = 0; xk = 0; yk = 0;
    }

    while (ck > 0 && xk >= xs0) {///x -> t; y -> p; first insertion and then match/mismatch
        --ck;
        op = in->a[ck]>>14;
        // ol = (((op == 1) || (op == 2))?(in->a[ck]&(0xfff)):(in->a[ck]&(0x3fff)));
        if((op == 2) || (op == 3)) {
            ol = in->a[ck]&(0xfff);
        } else if(op == 1) {
            ol = in->a[ck]&(0x3ff);
        } else {
            ol = in->a[ck]&(0x3fff);
        }
        if(op != 2) xk -= ol;
        if(op != 3) yk -= ol;
    }

    while (ck < cn && xk < xe0) {
        wx[0] = xk; wy[0] = yk; 
        // ck = pop_trace_bp(in, ck, &op, &b, &cl);
        ck = pop_trace_bp_f(in, ck, &op, &bq, &bt, &cl);
        if(op != 2) xk += cl;
        if(op != 3) yk += cl;
        wx[1] = xk; wy[1] = yk;  
        if(op == 0) {
            os = MAX(xs0, wx[0]); oe = MIN(xe0, wx[1]);
            ovlp = ((oe>os)? (oe-os):0);
            if((ovlp > 0) && (ovlp > (*rxe) - (*rxs))) {
                (*rxs) = wy[0] + os - wx[0]; 
                (*rxe) = wy[0] + oe - wx[0]; 

                (*rys) = ys0 + os - xs0; 
                (*rye) = ys0 + oe - xs0; 
            }
        }
    }

    *exk = xk; *eyk = yk; *eck = ck;
    if((*rxe) > (*rxs)) return 1;
    return 0; 
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
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 -0x38(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movq 0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x48(%rbp)
movq 0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x58(%rbp)
movq 0x38(%rbp), %rax
movq $0x0, (%rax)
movq 0x30(%rbp), %rax
movq $0x0, (%rax)
movq 0x28(%rbp), %rax
movq $0x0, (%rax)
movq 0x20(%rbp), %rax
movq $0x0, (%rax)
cmpq $0x0, -0x50(%rbp)
jl 0x255c04
movq -0x50(%rbp), %rax
cmpq -0x58(%rbp), %rax
jle 0x255c1c
movq $0x0, -0x50(%rbp)
movq $0x0, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
jmp 0x255c1e
xorl %eax, %eax
cmpq $0x0, -0x50(%rbp)
movb %al, -0xa1(%rbp)
jle 0x255c3e
movq -0x40(%rbp), %rax
cmpq -0x18(%rbp), %rax
setge %al
movb %al, -0xa1(%rbp)
movb -0xa1(%rbp), %al
testb $0x1, %al
jne 0x255c4d
jmp 0x255d29
movq -0x50(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x50(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x50(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
sarl $0xe, %eax
movw %ax, -0x92(%rbp)
movzwl -0x92(%rbp), %eax
cmpl $0x2, %eax
je 0x255c8b
movzwl -0x92(%rbp), %eax
cmpl $0x3, %eax
jne 0x255ca8
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x50(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
andl $0xfff, %eax            # imm = 0xFFF
cltq
movq %rax, -0x60(%rbp)
jmp 0x255cee
movzwl -0x92(%rbp), %eax
cmpl $0x1, %eax
jne 0x255cd1
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x50(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x3ff, %eax            # imm = 0x3FF
cltq
movq %rax, -0x60(%rbp)
jmp 0x255cec
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq -0x50(%rbp), %rcx
movzwl (%rax,%rcx,2), %eax
andl $0x3fff, %eax           # imm = 0x3FFF
cltq
movq %rax, -0x60(%rbp)
jmp 0x255cee
movzwl -0x92(%rbp), %eax
cmpl $0x2, %eax
je 0x255d09
movq -0x60(%rbp), %rcx
movq -0x40(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x40(%rbp)
movzwl -0x92(%rbp), %eax
cmpl $0x3, %eax
je 0x255d24
movq -0x60(%rbp), %rcx
movq -0x48(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x48(%rbp)
jmp 0x255c1e
jmp 0x255d2b
movq -0x50(%rbp), %rcx
xorl %eax, %eax
cmpq -0x58(%rbp), %rcx
movb %al, -0xa2(%rbp)
jge 0x255d4e
movq -0x40(%rbp), %rax
cmpq -0x20(%rbp), %rax
setl %al
movb %al, -0xa2(%rbp)
movb -0xa2(%rbp), %al
testb $0x1, %al
jne 0x255d5d
jmp 0x255f12
movq -0x40(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x10(%rbp), %rdi
movq -0x50(%rbp), %rax
movl %eax, %esi
leaq -0x92(%rbp), %rdx
leaq -0x94(%rbp), %rcx
leaq -0x96(%rbp), %r8
leaq -0x9c(%rbp), %r9
callq 0x1b53f0
movl %eax, %eax
movq %rax, -0x50(%rbp)
movzwl -0x92(%rbp), %eax
cmpl $0x2, %eax
je 0x255db8
movl -0x9c(%rbp), %eax
addq -0x40(%rbp), %rax
movq %rax, -0x40(%rbp)
movzwl -0x92(%rbp), %eax
cmpl $0x3, %eax
je 0x255dd2
movl -0x9c(%rbp), %eax
addq -0x48(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x78(%rbp)
movzwl -0x92(%rbp), %eax
cmpl $0x0, %eax
jne 0x255f0d
movq -0x18(%rbp), %rax
cmpq -0x70(%rbp), %rax
jl 0x255e09
movq -0x18(%rbp), %rax
movq %rax, -0xb0(%rbp)
jmp 0x255e14
movq -0x70(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
movq %rax, -0x88(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x68(%rbp), %rax
jg 0x255e39
movq -0x20(%rbp), %rax
movq %rax, -0xb8(%rbp)
jmp 0x255e44
movq -0x68(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rax
cmpq -0x88(%rbp), %rax
jle 0x255e79
movq -0x90(%rbp), %rax
subq -0x88(%rbp), %rax
movq %rax, -0xc0(%rbp)
jmp 0x255e84
xorl %eax, %eax
movq %rax, -0xc0(%rbp)
jmp 0x255e84
movq -0xc0(%rbp), %rax
movl %eax, -0xa0(%rbp)
cmpl $0x0, -0xa0(%rbp)
jbe 0x255f0b
movl -0xa0(%rbp), %eax
movq 0x28(%rbp), %rcx
movq (%rcx), %rcx
movq 0x20(%rbp), %rdx
subq (%rdx), %rcx
cmpq %rcx, %rax
jbe 0x255f0b
movq -0x80(%rbp), %rcx
addq -0x88(%rbp), %rcx
subq -0x70(%rbp), %rcx
movq 0x20(%rbp), %rax
movq %rcx, (%rax)
movq -0x80(%rbp), %rcx
addq -0x90(%rbp), %rcx
subq -0x70(%rbp), %rcx
movq 0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rcx
addq -0x88(%rbp), %rcx
subq -0x18(%rbp), %rcx
movq 0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0x28(%rbp), %rcx
addq -0x90(%rbp), %rcx
subq -0x18(%rbp), %rcx
movq 0x38(%rbp), %rax
movq %rcx, (%rax)
jmp 0x255f0d
jmp 0x255d2b
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, (%rax)
movq -0x48(%rbp), %rcx
movq 0x10(%rbp), %rax
movq %rcx, (%rax)
movq -0x50(%rbp), %rcx
movq 0x18(%rbp), %rax
movq %rcx, (%rax)
movq 0x28(%rbp), %rax
movq (%rax), %rax
movq 0x20(%rbp), %rcx
cmpq (%rcx), %rax
jbe 0x255f4c
movl $0x1, -0x4(%rbp)
jmp 0x255f53
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xc0, %rsp
popq %rbp
retq
nop