// File: /workspace/github_c_makefile_star2_O3/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
movq %rsi, 0x10(%rsp)
xorl %ebx, %ebx
movl $0x0, %r15d
cmpl $0x2, %edx
jl 0x4d020
movl %edx, %eax
xorl %ebp, %ebp
movl $0x1, %r11d
movq (%rdi,%r11,8), %rsi
movl (%rsi), %esi
movslq %ebp, %r10
movq (%rdi,%r10,8), %r10
movl %r11d, %r15d
cmpl (%r10), %esi
jg 0x4d015
movl %ebp, %r15d
incq %r11
movl %r15d, %ebp
cmpq %r11, %rax
jne 0x4cffd
movq %rdx, 0x20(%rsp)
movq (%rdi), %rax
cmpl $0x2, %ecx
jl 0x4d052
movl %ecx, %r14d
xorl %esi, %esi
movl $0x1, %edx
movl (%rax,%rdx,4), %r10d
movslq %esi, %r11
movl %edx, %ebx
cmpl (%rax,%r11,4), %r10d
jg 0x4d048
movl %esi, %ebx
incq %rdx
movl %ebx, %esi
cmpq %rdx, %r14
jne 0x4d037
movq 0x98(%rsp), %r12
movq 0x90(%rsp), %r13
movslq %r15d, %r10
movq (%rdi,%r10,8), %rdx
movl (%rdx), %esi
movslq %ebx, %rdx
cmpl (%rax,%rdx,4), %esi
jle 0x4d09c
testl %r15d, %r15d
movq 0x20(%rsp), %r11
jle 0x4d0c4
xorl %ebx, %ebx
xorl %eax, %eax
movb (%r8,%rax), %dl
movb %dl, (%r13,%rax)
movb $0x2d, (%r12,%rax)
incq %rax
cmpq %rax, %r10
jne 0x4d081
movl %r15d, %ebp
jmp 0x4d0cd
testl %ebx, %ebx
movq 0x20(%rsp), %r11
jle 0x4d0c8
xorl %r15d, %r15d
xorl %eax, %eax
movb $0x2d, (%r13,%rax)
movb (%r9,%rax), %sil
movb %sil, (%r12,%rax)
incq %rax
cmpq %rax, %rdx
jne 0x4d0aa
movl %ebx, %ebp
jmp 0x4d0cd
xorl %ebx, %ebx
jmp 0x4d0cb
xorl %r15d, %r15d
xorl %ebp, %ebp
movslq %r15d, %rsi
movb (%r8,%rsi), %al
movl %ebp, %edx
movb %al, (%r13,%rdx)
movslq %ebx, %r10
movb (%r9,%r10), %al
movb %al, (%r12,%rdx)
leal -0x1(%r11), %eax
movq %rcx, 0x38(%rsp)
leal -0x1(%rcx), %r14d
incl %ebp
movq %r10, 0x40(%rsp)
cmpl %r14d, %r10d
setl %cl
movq %rsi, 0x48(%rsp)
movl %eax, 0xc(%rsp)
cmpl %eax, %esi
setl %dl
jge 0x4d268
cmpl %r14d, %ebx
jge 0x4d268
leaq 0x1(%r8), %rax
movq %rax, 0x50(%rsp)
movq %r9, 0x28(%rsp)
movq %r8, 0x18(%rsp)
movq 0x10(%rsp), %r11
movslq %r15d, %rdx
movq (%r11,%rdx,8), %rcx
movslq %ebx, %rsi
movl (%rcx,%rsi,8), %eax
movl 0x4(%rcx,%rsi,8), %ecx
leal 0x1(%rdx), %r10d
incl %esi
cmpl %r10d, %eax
jne 0x4d15f
cmpl %esi, %ecx
jne 0x4d15f
movl %ecx, %ebx
movl %eax, %r15d
jmp 0x4d217
cmpl %esi, %ecx
jne 0x4d1b2
movl 0xc(%rsp), %esi
cmpl %esi, %eax
cmovgel %esi, %eax
cmpl %eax, %r10d
jge 0x4d206
movslq %ebp, %rsi
leaq (%rsi,%r13), %r11
addq %r12, %rsi
movq 0x50(%rsp), %r8
addq %rdx, %r8
notl %edx
addl %eax, %edx
xorl %r9d, %r9d
movb (%r8,%r9), %r10b
movb %r10b, (%r11,%r9)
movb $0x2d, (%rsi,%r9)
incq %r9
cmpl %r9d, %edx
jne 0x4d18e
addl %r9d, %ebp
movl %ecx, %ebx
movl %eax, %r15d
movq 0x28(%rsp), %r9
jmp 0x4d1fa
cmpl %r10d, %eax
jne 0x4d24d
cmpl %r14d, %ecx
cmovgel %r14d, %ecx
cmpl %ecx, %esi
jge 0x4d20d
movslq %esi, %rdx
movslq %ebp, %rsi
leaq (%rsi,%r13), %r10
addq %r12, %rsi
addq %r9, %rdx
notl %ebx
addl %ecx, %ebx
xorl %r8d, %r8d
movb $0x2d, (%r10,%r8)
movb (%rdx,%r8), %r11b
movb %r11b, (%rsi,%r8)
incq %r8
cmpl %r8d, %ebx
jne 0x4d1dd
addl %r8d, %ebp
movl %ecx, %ebx
movl %eax, %r15d
movq 0x18(%rsp), %r8
movq 0x10(%rsp), %r11
jmp 0x4d217
movl %ecx, %ebx
movl %r10d, %r15d
jmp 0x4d217
movl %esi, %ebx
movl %eax, %r15d
movq 0x18(%rsp), %r8
movslq %r15d, %rax
movb (%r8,%rax), %cl
movslq %ebp, %rbp
movb %cl, (%r13,%rbp)
movslq %ebx, %rcx
movb (%r9,%rcx), %dl
movb %dl, (%r12,%rbp)
incl %ebp
cmpl %r14d, %ecx
setl %cl
cmpl 0xc(%rsp), %eax
setl %dl
jge 0x4d268
cmpl %r14d, %ebx
jl 0x4d135
jmp 0x4d268
movq %rdi, 0x30(%rsp)
callq 0x22f0
movq 0x10(%rsp), %r11
movq 0x28(%rsp), %r9
movq 0x30(%rsp), %rdi
jmp 0x4d212
movq 0xa0(%rsp), %rax
testb %dl, %dl
je 0x4d2af
movslq %r15d, %rcx
incq %rcx
movq 0x20(%rsp), %rsi
cmpl %esi, %ecx
jge 0x4d2f3
movslq %ebp, %rdx
addq %rdx, %r13
addq %rdx, %r12
addq %rcx, %r8
notl %r15d
addl %esi, %r15d
xorl %ecx, %ecx
movb (%r8,%rcx), %dl
movb %dl, (%r13,%rcx)
movb $0x2d, (%r12,%rcx)
incq %rcx
cmpl %ecx, %r15d
jne 0x4d297
jmp 0x4d2f1
leal 0x1(%rbx), %edx
movq 0x38(%rsp), %r8
cmpl %r8d, %edx
setge %sil
xorb $0x1, %cl
orb %sil, %cl
jne 0x4d2f3
movslq %edx, %rcx
movslq %ebp, %rdx
addq %rdx, %r13
addq %rdx, %r12
addq %rcx, %r9
notl %ebx
addl %r8d, %ebx
xorl %ecx, %ecx
movb $0x2d, (%r13,%rcx)
movb (%r9,%rcx), %dl
movb %dl, (%r12,%rcx)
incq %rcx
cmpl %ecx, %ebx
jne 0x4d2dc
addl %ecx, %ebp
movl %ebp, (%rax)
movq 0x48(%rsp), %rax
movq (%rdi,%rax,8), %rax
movq 0x40(%rsp), %rcx
movl (%rax,%rcx,4), %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq