// File: /workspace/github_c_makefile_star2_O2/ugobas[P]tnm/NeedlemanWunsch.c
// Function: TraceBack
static int TraceBack(int  **matrix,
                     XY   **dirn,
                     int  length1,
                     int  length2,
                     char *seq1,
                     char *seq2,
                     char *align1,
                     char *align2,
                     int  *align_len)
{
   int   i,    j,
         ai,
         BestI,BestJ;
   XY    nextCell;

   ai = SearchForBest(matrix, length1, length2, &BestI, &BestJ,
                       seq1, seq2, align1, align2);

   /* Now trace back to find the alignment                              */
   i            = BestI;
   j            = BestJ;
   align1[ai]   = seq1[i];
   align2[ai++] = seq2[j];

   while(i < length1-1 && j < length2-1)
   {
      nextCell.x = dirn[i][j].x;
      nextCell.y = dirn[i][j].y;
      if((nextCell.x == i+1) && (nextCell.y == j+1))
      {
         /* We are inheriting from the diagonal                         */
         i++;
         j++;
      }
      else if(nextCell.y == j+1)
      {
         /* We are inheriting from the off-diagonal inserting a gap in
            the y-sequence (seq2)
         */
         i++;
         j++;
         while((i < nextCell.x) && (i < length1-1))
         {
            align1[ai] = seq1[i++];
            align2[ai++] = '-';
         }
      }
      else if(nextCell.x == i+1)
      {
         /* We are inheriting from the off-diagonal inserting a gap in
            the x-sequence (seq1)
         */
         i++;
         j++;
         while((j < nextCell.y) && (j < length2-1))
         {
            align1[ai] = '-';
            align2[ai++] = seq2[j++];
         }
      }
      else
      {
         /* Cockup!                                                     */
         fprintf(stderr,"align.c/TraceBack() internal error\n");
      }

      align1[ai]   = seq1[i];
      align2[ai++] = seq2[j];
   }

   /* If one sequence finished first, fill in the end with insertions   */
   if(i < length1-1)
   {
      for(j=i+1; j<length1; j++)
      {
         align1[ai]   = seq1[j];
         align2[ai++] = '-';
      }
   }
   else if(j < length2-1)
   {
      for(i=j+1; i<length2; i++)
      {
         align1[ai]   = '-';
         align2[ai++] = seq2[i];
      }
   }

   *align_len = ai;

   return(matrix[BestI][BestJ]);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %ecx, (%rsp)
movq %rsi, 0x50(%rsp)
movq 0x98(%rsp), %rbx
movq 0x90(%rsp), %rbp
movl %edx, 0x4(%rsp)
movslq %edx, %r15
xorl %r14d, %r14d
pushq $0x1
popq %rax
movslq %r14d, %rcx
cmpq %r15, %rax
jge 0x46c35
movq (%rdi,%rax,8), %rdx
movl (%rdx), %edx
movq (%rdi,%rcx,8), %rsi
movl %eax, %ecx
cmpl (%rsi), %edx
jg 0x46c2d
movl %r14d, %ecx
incq %rax
movl %ecx, %r14d
jmp 0x46c12
movslq (%rsp), %rax
movq %rax, 0x28(%rsp)
xorl %r12d, %r12d
pushq $0x1
popq %rdx
movslq %r12d, %rax
cmpq 0x28(%rsp), %rdx
jge 0x46c68
movq (%rdi), %r10
movl (%r10,%rdx,4), %r11d
movl %edx, %esi
cmpl (%r10,%rax,4), %r11d
jg 0x46c60
movl %r12d, %esi
incq %rdx
movl %esi, %r12d
jmp 0x46c44
movq (%rdi,%rcx,8), %rdx
movl (%rdx), %edx
movq (%rdi), %rsi
cmpl (%rsi,%rax,4), %edx
movq %rdi, 0x38(%rsp)
movq %r15, 0x30(%rsp)
jle 0x46ca2
xorl %r12d, %r12d
testq %rcx, %rcx
cmovleq %r12, %rcx
xorl %eax, %eax
cmpq %rax, %rcx
je 0x46cc4
movb (%r8,%rax), %dl
movb %dl, (%rbp,%rax)
movb $0x2d, (%rbx,%rax)
incq %rax
jmp 0x46c8c
xorl %r14d, %r14d
testq %rax, %rax
cmovleq %r14, %rax
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x46cc7
movb $0x2d, (%rbp,%rcx)
movb (%r9,%rcx), %dl
movb %dl, (%rbx,%rcx)
incq %rcx
jmp 0x46cae
movq %rcx, %rax
movslq %r14d, %rcx
movq %rcx, 0x20(%rsp)
movb (%r8,%rcx), %cl
movb %cl, (%rbp,%rax)
movslq %r12d, %rcx
movq %rcx, 0x18(%rsp)
movb (%r9,%rcx), %cl
movb %cl, (%rbx,%rax)
decl 0x4(%rsp)
decl (%rsp)
leaq 0x1(%r9), %rcx
movq %rcx, 0x40(%rsp)
leaq 0x1(%r8), %rcx
movq %rcx, 0x48(%rsp)
movq %r9, 0x10(%rsp)
movq %r8, 0x8(%rsp)
leal 0x1(%rax), %r15d
movslq %r14d, %rsi
movslq %r12d, %rdx
movslq %r15d, %rcx
cmpl 0x4(%rsp), %r14d
jge 0x46e5c
cmpl (%rsp), %r12d
jge 0x46e5c
movq 0x50(%rsp), %rax
movq (%rax,%rsi,8), %rdi
movl (%rdi,%rdx,8), %eax
movl 0x4(%rdi,%rdx,8), %edi
leal 0x1(%r14), %r13d
leal 0x1(%r12), %ebx
cmpl %r13d, %eax
jne 0x46d58
cmpl %ebx, %edi
jne 0x46d58
movl %edi, %r12d
movl %eax, %r14d
jmp 0x46e16
cmpl %ebx, %edi
jne 0x46d9f
movl 0x4(%rsp), %edx
cmpl %edx, %eax
cmovgel %edx, %eax
cltq
movq 0x48(%rsp), %rdx
addq %rsi, %rdx
incq %rsi
leaq (%rcx,%rbp), %r10
movq 0x98(%rsp), %rbx
addq %rbx, %rcx
xorl %r9d, %r9d
leaq (%rsi,%r9), %r11
cmpq %rax, %r11
jge 0x46de8
movb (%rdx,%r9), %r11b
movb %r11b, (%r10,%r9)
movb $0x2d, (%rcx,%r9)
incq %r9
jmp 0x46d84
cmpl %r13d, %eax
jne 0x46e3e
movl (%rsp), %esi
cmpl %esi, %edi
cmovgel %esi, %edi
movslq %edi, %rsi
movq 0x40(%rsp), %rdi
addq %rdx, %rdi
incq %rdx
leaq (%rcx,%rbp), %r10
addq 0x98(%rsp), %rcx
xorl %r8d, %r8d
leaq (%rdx,%r8), %r11
cmpq %rsi, %r11
jge 0x46e00
movb $0x2d, (%r10,%r8)
movb (%rdi,%r8), %r11b
movb %r11b, (%rcx,%r8)
incq %r8
jmp 0x46dcd
addl %r9d, %r13d
addl %r9d, %r15d
movl %edi, %r12d
movl %r13d, %r14d
movq 0x10(%rsp), %r9
movq 0x8(%rsp), %r8
jmp 0x46e1e
addl %r8d, %ebx
addl %r8d, %r15d
movl %ebx, %r12d
movl %eax, %r14d
movq 0x10(%rsp), %r9
movq 0x8(%rsp), %r8
movq 0x98(%rsp), %rbx
movslq %r14d, %rax
movb (%r8,%rax), %al
movslq %r15d, %rcx
movb %al, (%rbp,%rcx)
movslq %r12d, %rax
movb (%r9,%rax), %al
movb %al, (%rbx,%rcx)
movl %r15d, %eax
jmp 0x46d09
movq 0x1b1b3(%rip), %rax     # 0x61ff8
movq (%rax), %rcx
leaq 0x1139d(%rip), %rdi     # 0x581ec
pushq $0x23
popq %rsi
pushq $0x1
popq %rdx
callq 0x2280
jmp 0x46e0c
cmpl 0x4(%rsp), %r14d
jge 0x46e99
incq %rsi
addq %rcx, %rbp
addq %rcx, %rbx
xorl %ecx, %ecx
movq 0xa0(%rsp), %rdi
movq 0x30(%rsp), %r9
movq 0x18(%rsp), %r10
cmpq %r9, %rsi
jge 0x46ed8
movb (%r8,%rsi), %dl
movb %dl, (%rbp,%rcx)
movb $0x2d, (%rbx,%rcx)
incq %rsi
incq %rcx
jmp 0x46e80
cmpl (%rsp), %r12d
movq 0xa0(%rsp), %rdi
movq 0x20(%rsp), %r8
movq 0x18(%rsp), %r10
jge 0x46eed
incq %rdx
addq %rcx, %rbp
addq %rcx, %rbx
xorl %ecx, %ecx
cmpq 0x28(%rsp), %rdx
jge 0x46ee6
movb $0x2d, (%rbp,%rcx)
movb (%r9,%rdx), %sil
movb %sil, (%rbx,%rcx)
incq %rdx
incq %rcx
jmp 0x46ebc
leal (%rax,%rcx), %r15d
incl %r15d
movq 0x20(%rsp), %r8
jmp 0x46eed
leal (%rax,%rcx), %r15d
incl %r15d
movl %r15d, (%rdi)
movq 0x38(%rsp), %rax
movq (%rax,%r8,8), %rax
movl (%rax,%r10,4), %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq