// File: /workspace/github_c_makefile_star2_O3/icebert[P]pblat/lib/chainBlock.c
// Function: bestPredecessor
static struct predScore bestPredecessor(
	struct kdLeaf *lonely,	    /* We're finding this leaf's predecessor */
	ConnectCost connectCost,    /* Cost to connect two leafs. */
	GapCost gapCost,	    /* Lower bound on gap cost. */
	void *gapData,		    /* Data to pass to Gap/Connect cost */
	int dim,		    /* Dimension level of tree splits on. */
	struct kdBranch *branch,    /* Subtree to explore */
	struct predScore bestSoFar) /* Best predecessor so far. */
/* Find the highest scoring predecessor to this leaf, and
 * thus iteratively the highest scoring subchain that ends
 * in this leaf. */
{
struct kdLeaf *leaf;
double maxScore = branch->maxScore + lonely->cb->score;

/* If best score in this branch of tree wouldn't be enough
 * don't bother exploring it. First try without calculating
 * gap score in case gap score is a little expensive to calculate. */
if (maxScore < bestSoFar.score)
    return bestSoFar;
maxScore -= gapCost(lonely->cb->qStart - branch->maxQ, 
	lonely->cb->tStart - branch->maxT, gapData);
if (maxScore < bestSoFar.score)
    return bestSoFar;


/* If it's a terminal branch, then calculate score to connect
 * with it. */
else if ((leaf = branch->leaf) != NULL)
    {
    if (leaf->cb->qStart < lonely->cb->qStart 
     && leaf->cb->tStart < lonely->cb->tStart)
	{
	double score = leaf->totalScore + lonely->cb->score - 
		connectCost(leaf->cb, lonely->cb, gapData);
	if (score > bestSoFar.score)
	   {
	   bestSoFar.score = score;
	   bestSoFar.pred = branch;
	   }
	}
    return bestSoFar;
    }

/* Otherwise explore sub-trees that could harbor predecessors. */
else
    {
    int newDim = 1-dim;
    int dimCoord = (dim == 0 ? lonely->cb->qStart : lonely->cb->tStart);
    
    /* Explore hi branch first as it is more likely to have high
     * scores.  However only explore it if it can have things starting
     * before us. */
    if (dimCoord > branch->cutCoord)
         bestSoFar = bestPredecessor(lonely, connectCost, gapCost, gapData,
	 	newDim, branch->hi, bestSoFar);
    bestSoFar = bestPredecessor(lonely, connectCost, gapCost, gapData,
    	newDim, branch->lo, bestSoFar);
    return bestSoFar;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq 0x8(%rdi), %rax
cvtsi2sdl 0x18(%rax), %xmm1
addsd 0x20(%r9), %xmm1
leaq 0x60(%rsp), %r15
movsd 0x8(%r15), %xmm0
ucomisd %xmm1, %xmm0
ja 0x1fd53
movq %r9, %rbx
movl %r8d, %ebp
movq %rcx, %r14
movq %rdx, %r12
movq %rdi, %r13
movq %rsi, 0x10(%rsp)
movl 0x8(%rax), %esi
movl 0x10(%rax), %edi
subl 0x28(%r9), %edi
subl 0x2c(%r9), %esi
movq %rcx, %rdx
movsd %xmm0, 0x20(%rsp)
movsd %xmm1, 0x18(%rsp)
callq *%r12
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd 0x18(%rsp), %xmm1
subsd %xmm0, %xmm1
movsd 0x20(%rsp), %xmm0
ucomisd %xmm1, %xmm0
ja 0x1fd53
movq 0x10(%rbx), %rax
testq %rax, %rax
je 0x1fd65
movq 0x8(%rax), %rdi
movl 0x10(%rdi), %ecx
movq 0x8(%r13), %rsi
cmpl 0x10(%rsi), %ecx
jge 0x1fd53
movl 0x8(%rdi), %ecx
cmpl 0x8(%rsi), %ecx
jge 0x1fd53
xorps %xmm0, %xmm0
cvtsi2sdl 0x18(%rsi), %xmm0
addsd 0x18(%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq %r14, %rdx
callq *0x10(%rsp)
movsd 0x18(%rsp), %xmm1
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
subsd %xmm0, %xmm1
movsd 0x20(%rsp), %xmm0
ucomisd %xmm0, %xmm1
jbe 0x1fd53
movq %rbx, (%r15)
movapd %xmm1, %xmm0
movq (%r15), %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x1, %r8d
subl %ebp, %r8d
xorl %eax, %eax
testl %ebp, %ebp
sete %al
movq 0x8(%r13), %rcx
movl 0x8(%rcx,%rax,8), %eax
cmpl 0x18(%rbx), %eax
jle 0x1fdb2
movq 0x8(%rbx), %r9
movupd (%r15), %xmm0
movupd %xmm0, (%rsp)
movq %r13, %rdi
movq 0x10(%rsp), %rsi
movq %r12, %rdx
movq %r14, %rcx
movl %r8d, %ebp
callq 0x1fc71
movl %ebp, %r8d
movq %rax, (%r15)
movsd %xmm0, 0x8(%r15)
movq (%rbx), %r9
movupd (%r15), %xmm0
movupd %xmm0, (%rsp)
movq %r13, %rdi
movq 0x10(%rsp), %rsi
movq %r12, %rdx
movq %r14, %rcx
callq 0x1fc71
jmp 0x1fd56