// File: tedsharpe[P]ORFCall/ORFCall.cc
// Function: (anonymous namespace)::SmithWatermanizer::score(__gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char>>>, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char>>>, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char>>>, __gnu_cxx::__normal_iterator<unsigned char const*, std::vector<unsigned char, std::allocator<unsigned char>>>)
void SmithWatermanizer::score( Sequence::const_iterator bX,
                               Sequence::const_iterator eX,
                               Sequence::const_iterator bY,
                               Sequence::const_iterator eY )
{
    using std::distance;
    auto nCols = distance(bX,eX);
    mVScores.resize(nCols);
    mMaxScores.resize(nCols);
    mTraceback.resize((nCols+1)*(distance(bY,eY)+1));
    Trace* pTrace = &mTraceback.front();
    *pTrace++ = Trace::DONE;
    std::fill(pTrace,pTrace+nCols,Trace::LEFT);
    pTrace += nCols;
    int rowInit = 0;//GAP_OPEN;
    int colInit = GAP_OPEN;
    Call baseX0 = *bX;

    Call baseY = *bY;
    int* pVScore = &mVScores.front();
    int* pMaxScore = &mMaxScores.front();
    *pTrace++ = Trace::UP;

    // (0,0) can't extend any gaps
    int dScore = (baseX0==baseY ? MATCH : MIS_MATCH);
    int hScore = rowInit + GAP_OPEN;
    int vScore = colInit + GAP_OPEN;
    int maxScore = max3(dScore,hScore,vScore,pTrace++);

    *pVScore++ = vScore;
    *pMaxScore++ = maxScore;

    // (1..n,0) can't extend vGap
    for ( Sequence::const_iterator iX=++bX; iX != eX; ++iX )
    {
        dScore = colInit + (*iX==baseY ? MATCH : MIS_MATCH);
        if ( pTrace[-1] == Trace::LEFT )
            hScore = std::max(maxScore+GAP_OPEN,hScore+GAP_EXTEND);
        else
            hScore = maxScore + GAP_OPEN;
        colInit += GAP_EXTEND;
        vScore = colInit + GAP_OPEN;
        maxScore = max3(dScore,hScore,vScore,pTrace++);

        *pVScore++ = vScore;
        *pMaxScore++ = maxScore;
    }

    int bestRowScore = maxScore;
    Trace* pBestTrace = pTrace;

    int maxScorePrevRow;
    while ( ++bY != eY )
    {
        baseY = *bY;
        pVScore = &mVScores.front();
        pMaxScore = &mMaxScores.front();
        *pTrace++ = Trace::UP;

        // (0,1..m) can't extend hGap
        dScore = rowInit + (baseX0==baseY ? MATCH : MIS_MATCH);
        //rowInit += GAP_EXTEND;
        hScore = rowInit + GAP_OPEN;
        maxScorePrevRow = *pMaxScore;
        vScore = std::max(maxScorePrevRow+GAP_OPEN,*pVScore+GAP_EXTEND);
        maxScore = max3(dScore,hScore,vScore,pTrace++);

        *pVScore++ = vScore;
        *pMaxScore++ = maxScore;

        // (1..n,1..m) general case
        for ( Sequence::const_iterator iX=bX; iX != eX; ++iX )
        {
            dScore = maxScorePrevRow + (*iX==baseY ? MATCH : MIS_MATCH);
            if ( pTrace[-1] == Trace::LEFT )
                hScore = std::max(maxScore+GAP_OPEN,hScore+GAP_EXTEND);
            else
                hScore = maxScore + GAP_OPEN;
            maxScorePrevRow = *pMaxScore;
            if ( pTrace[-nCols-1] == Trace::UP )
                vScore = std::max(maxScorePrevRow+GAP_OPEN,*pVScore+GAP_EXTEND);
            else
                vScore = maxScorePrevRow + GAP_OPEN;
            maxScore = max3(dScore,hScore,vScore,pTrace++);

            *pVScore++ = vScore;
            *pMaxScore++ = maxScore;
        }

        if ( maxScore > bestRowScore )
        {
            bestRowScore = maxScore;
            pBestTrace = pTrace;
        }
    }
    mpBestTracebackStart = pBestTrace-1;
}

// Assembly:
subq $0xf8, %rsp
movq %rsi, 0xf0(%rsp)
movq %rdx, 0xe8(%rsp)
movq %rcx, 0xe0(%rsp)
movq %r8, 0xd8(%rsp)
movq %rdi, 0xd0(%rsp)
movq 0xd0(%rsp), %rax
movq %rax, 0x20(%rsp)
movq 0xf0(%rsp), %rax
movq %rax, 0xc0(%rsp)
movq 0xe8(%rsp), %rax
movq %rax, 0xb8(%rsp)
movq 0xc0(%rsp), %rdi
movq 0xb8(%rsp), %rsi
callq 0x1f040
movq 0x20(%rsp), %rdi
movq %rax, 0xc8(%rsp)
addq $0x18, %rdi
movq 0xc8(%rsp), %rsi
callq 0x1f080
movq 0x20(%rsp), %rdi
movq 0xc8(%rsp), %rsi
callq 0x1f080
movq 0x20(%rsp), %rax
addq $0x30, %rax
movq %rax, 0x18(%rsp)
movq 0xc8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x10(%rsp)
movq 0xe0(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0xd8(%rsp), %rax
movq %rax, 0xa8(%rsp)
movq 0xb0(%rsp), %rdi
movq 0xa8(%rsp), %rsi
callq 0x1f040
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdi
addq $0x1, %rax
imulq %rax, %rsi
callq 0x11630
movq 0x20(%rsp), %rdi
addq $0x30, %rdi
callq 0x116d0
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0xa0(%rsp)
movb $0x0, (%rax)
movq 0xa0(%rsp), %rdi
movq 0xa0(%rsp), %rsi
addq 0xc8(%rsp), %rsi
movb $0x2, 0x9f(%rsp)
leaq 0x9f(%rsp), %rdx
callq 0x11700
movq 0xc8(%rsp), %rax
addq 0xa0(%rsp), %rax
movq %rax, 0xa0(%rsp)
movl $0x0, 0x98(%rsp)
movl $0xfffffff2, 0x94(%rsp) # imm = 0xFFFFFFF2
leaq 0xf0(%rsp), %rdi
callq 0x1a180
movb (%rax), %al
movb %al, 0x93(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x1a180
movq 0x20(%rsp), %rdi
movb (%rax), %al
movb %al, 0x92(%rsp)
addq $0x18, %rdi
callq 0x1f120
movq 0x20(%rsp), %rdi
movq %rax, 0x88(%rsp)
callq 0x1f120
movq %rax, 0x80(%rsp)
movq 0xa0(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0xa0(%rsp)
movb $0x1, (%rax)
movzbl 0x93(%rsp), %edx
movzbl 0x92(%rsp), %esi
movl $0xfffffffa, %eax       # imm = 0xFFFFFFFA
movl $0x4, %ecx
cmpl %esi, %edx
cmovel %ecx, %eax
movl %eax, 0x7c(%rsp)
movl 0x98(%rsp), %eax
addl $-0xe, %eax
movl %eax, 0x78(%rsp)
movl 0x94(%rsp), %eax
addl $-0xe, %eax
movl %eax, 0x74(%rsp)
movl 0x7c(%rsp), %edi
movl 0x78(%rsp), %esi
movl 0x74(%rsp), %edx
movq 0xa0(%rsp), %rcx
movq %rcx, %rax
addq $0x1, %rax
movq %rax, 0xa0(%rsp)
callq 0x11730
movl %eax, 0x70(%rsp)
movl 0x74(%rsp), %ecx
movq 0x88(%rsp), %rax
movq %rax, %rdx
addq $0x4, %rdx
movq %rdx, 0x88(%rsp)
movl %ecx, (%rax)
movl 0x70(%rsp), %ecx
movq 0x80(%rsp), %rax
movq %rax, %rdx
addq $0x4, %rdx
movq %rdx, 0x80(%rsp)
movl %ecx, (%rax)
leaq 0xf0(%rsp), %rdi
callq 0x19f60
movq (%rax), %rax
movq %rax, 0x68(%rsp)
leaq 0x68(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x19f20
testb $0x1, %al
jne 0x10baa
jmp 0x10cc0
movl 0x94(%rsp), %eax
movl %eax, 0xc(%rsp)
leaq 0x68(%rsp), %rdi
callq 0x1a180
movq %rax, %rcx
movl 0xc(%rsp), %eax
movzbl (%rcx), %esi
movzbl 0x92(%rsp), %edi
movl $0xfffffffa, %ecx       # imm = 0xFFFFFFFA
movl $0x4, %edx
cmpl %edi, %esi
cmovel %edx, %ecx
addl %ecx, %eax
movl %eax, 0x7c(%rsp)
movq 0xa0(%rsp), %rax
cmpb $0x2, -0x1(%rax)
jne 0x10c21
movl 0x70(%rsp), %eax
addl $-0xe, %eax
movl %eax, 0x64(%rsp)
movl 0x78(%rsp), %eax
addl $-0x3, %eax
movl %eax, 0x60(%rsp)
leaq 0x64(%rsp), %rdi
leaq 0x60(%rsp), %rsi
callq 0x1f150
movl (%rax), %eax
movl %eax, 0x78(%rsp)
jmp 0x10c2c
movl 0x70(%rsp), %eax
addl $-0xe, %eax
movl %eax, 0x78(%rsp)
movl 0x94(%rsp), %eax
addl $-0x3, %eax
movl %eax, 0x94(%rsp)
movl 0x94(%rsp), %eax
addl $-0xe, %eax
movl %eax, 0x74(%rsp)
movl 0x7c(%rsp), %edi
movl 0x78(%rsp), %esi
movl 0x74(%rsp), %edx
movq 0xa0(%rsp), %rcx
movq %rcx, %rax
addq $0x1, %rax
movq %rax, 0xa0(%rsp)
callq 0x11730
movl %eax, 0x70(%rsp)
movl 0x74(%rsp), %ecx
movq 0x88(%rsp), %rax
movq %rax, %rdx
addq $0x4, %rdx
movq %rdx, 0x88(%rsp)
movl %ecx, (%rax)
movl 0x70(%rsp), %ecx
movq 0x80(%rsp), %rax
movq %rax, %rdx
addq $0x4, %rdx
movq %rdx, 0x80(%rsp)
movl %ecx, (%rax)
leaq 0x68(%rsp), %rdi
callq 0x19f60
jmp 0x10b8f
movl 0x70(%rsp), %eax
movl %eax, 0x5c(%rsp)
movq 0xa0(%rsp), %rax
movq %rax, 0x50(%rsp)
leaq 0xe0(%rsp), %rdi
callq 0x19f60
movq %rax, %rdi
leaq 0xd8(%rsp), %rsi
callq 0x19f20
testb $0x1, %al
jne 0x10cfb
jmp 0x10fda
leaq 0xe0(%rsp), %rdi
callq 0x1a180
movq 0x20(%rsp), %rdi
movb (%rax), %al
movb %al, 0x92(%rsp)
addq $0x18, %rdi
callq 0x1f120
movq 0x20(%rsp), %rdi
movq %rax, 0x88(%rsp)
callq 0x1f120
movq %rax, 0x80(%rsp)
movq 0xa0(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0xa0(%rsp)
movb $0x1, (%rax)
movl 0x98(%rsp), %eax
movzbl 0x93(%rsp), %esi
movzbl 0x92(%rsp), %edi
movl $0xfffffffa, %ecx       # imm = 0xFFFFFFFA
movl $0x4, %edx
cmpl %edi, %esi
cmovel %edx, %ecx
addl %ecx, %eax
movl %eax, 0x7c(%rsp)
movl 0x98(%rsp), %eax
addl $-0xe, %eax
movl %eax, 0x78(%rsp)
movq 0x80(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x4c(%rsp)
movl 0x4c(%rsp), %eax
addl $-0xe, %eax
movl %eax, 0x48(%rsp)
movq 0x88(%rsp), %rax
movl (%rax), %eax
addl $-0x3, %eax
movl %eax, 0x44(%rsp)
leaq 0x48(%rsp), %rdi
leaq 0x44(%rsp), %rsi
callq 0x1f150
movl (%rax), %eax
movl %eax, 0x74(%rsp)
movl 0x7c(%rsp), %edi
movl 0x78(%rsp), %esi
movl 0x74(%rsp), %edx
movq 0xa0(%rsp), %rcx
movq %rcx, %rax
addq $0x1, %rax
movq %rax, 0xa0(%rsp)
callq 0x11730
movl %eax, 0x70(%rsp)
movl 0x74(%rsp), %ecx
movq 0x88(%rsp), %rax
movq %rax, %rdx
addq $0x4, %rdx
movq %rdx, 0x88(%rsp)
movl %ecx, (%rax)
movl 0x70(%rsp), %ecx
movq 0x80(%rsp), %rax
movq %rax, %rdx
addq $0x4, %rdx
movq %rdx, 0x80(%rsp)
movl %ecx, (%rax)
movq 0xf0(%rsp), %rax
movq %rax, 0x38(%rsp)
leaq 0x38(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x19f20
testb $0x1, %al
jne 0x10e5a
jmp 0x10fb6
movl 0x4c(%rsp), %eax
movl %eax, 0x8(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x1a180
movq %rax, %rcx
movl 0x8(%rsp), %eax
movzbl (%rcx), %esi
movzbl 0x92(%rsp), %edi
movl $0xfffffffa, %ecx       # imm = 0xFFFFFFFA
movl $0x4, %edx
cmpl %edi, %esi
cmovel %edx, %ecx
addl %ecx, %eax
movl %eax, 0x7c(%rsp)
movq 0xa0(%rsp), %rax
cmpb $0x2, -0x1(%rax)
jne 0x10ece
movl 0x70(%rsp), %eax
addl $-0xe, %eax
movl %eax, 0x34(%rsp)
movl 0x78(%rsp), %eax
addl $-0x3, %eax
movl %eax, 0x30(%rsp)
leaq 0x34(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x1f150
movl (%rax), %eax
movl %eax, 0x78(%rsp)
jmp 0x10ed9
movl 0x70(%rsp), %eax
addl $-0xe, %eax
movl %eax, 0x78(%rsp)
movq 0x80(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x4c(%rsp)
movq 0xa0(%rsp), %rax
xorl %ecx, %ecx
subq 0xc8(%rsp), %rcx
subq $0x1, %rcx
cmpb $0x1, (%rax,%rcx)
jne 0x10f36
movl 0x4c(%rsp), %eax
addl $-0xe, %eax
movl %eax, 0x2c(%rsp)
movq 0x88(%rsp), %rax
movl (%rax), %eax
addl $-0x3, %eax
movl %eax, 0x28(%rsp)
leaq 0x2c(%rsp), %rdi
leaq 0x28(%rsp), %rsi
callq 0x1f150
movl (%rax), %eax
movl %eax, 0x74(%rsp)
jmp 0x10f41
movl 0x4c(%rsp), %eax
addl $-0xe, %eax
movl %eax, 0x74(%rsp)
movl 0x7c(%rsp), %edi
movl 0x78(%rsp), %esi
movl 0x74(%rsp), %edx
movq 0xa0(%rsp), %rcx
movq %rcx, %rax
addq $0x1, %rax
movq %rax, 0xa0(%rsp)
callq 0x11730
movl %eax, 0x70(%rsp)
movl 0x74(%rsp), %ecx
movq 0x88(%rsp), %rax
movq %rax, %rdx
addq $0x4, %rdx
movq %rdx, 0x88(%rsp)
movl %ecx, (%rax)
movl 0x70(%rsp), %ecx
movq 0x80(%rsp), %rax
movq %rax, %rdx
addq $0x4, %rdx
movq %rdx, 0x80(%rsp)
movl %ecx, (%rax)
leaq 0x38(%rsp), %rdi
callq 0x19f60
jmp 0x10e3f
movl 0x70(%rsp), %eax
cmpl 0x5c(%rsp), %eax
jle 0x10fd5
movl 0x70(%rsp), %eax
movl %eax, 0x5c(%rsp)
movq 0xa0(%rsp), %rax
movq %rax, 0x50(%rsp)
jmp 0x10cd5
movq 0x20(%rsp), %rax
movq 0x50(%rsp), %rcx
addq $-0x1, %rcx
movq %rcx, 0x48(%rax)
addq $0xf8, %rsp
retq
nopw %cs:(%rax,%rax)