// File: /workspace/github_c_makefile_star2_O2/genometools[P]genometools/src/mgth/mg_computepath.c
// Function: mg_computepath
int mg_computepath(CombinedScoreMatrixEntry **combinedscore_matrix,
                   HitInformation *hit_information,
                   GtUword rows,
                   GtUword contig_len,
                   ParseStruct *parsestruct_ptr, GtError * err)
{
  int had_err = 0;

  /* Initialisieren der Matrix fuer die Pfadberechnung */
  PathMatrixEntry **path_matrix;

  /* i: Zaehlvariable fuer die Matrix-Zeilen; k: Zaehlvariable Precursors
     (von 0 bis max 2) maxpath_frame: Speichern des vorherigen Frames von
     dem der max-Wert berechnet wird */
  unsigned short row_index = 0,
    precursor_index = 0,
    precursors_row = 0,
    maxpath_frame = 0;

  /* Position in der Query-DNA */
  GtUword column_index = 0;

  /* Variablen fuer den aktuellen Frame, den vorherigen Frame(speichert
     einen Wert aus precursors[], die Zeile des vorherigen Frames, GtArray
     mit den Precursors-Frames */
  short current_frame = 0,
    precursors_frame = 0,
    precursors[NUM_PRECURSORS];

  /* q ist der Wert, der bei Aus- oder Eintreten in ein Gen auf dem
     Forward- bzw. Reverse-Strang berechnet wird */
  double q = ARGUMENTSSTRUCT(leavegene_value),
    max_new = 1,
    max_old = 1;

  /* Speicherreservierung fuer die Path-Matrix - Groesse entsprechend der
     CombinedScore-Matrix */
  gt_array2dim_calloc(path_matrix, 7, contig_len);

  gt_error_check(err);

  /* fuer die erste Spalte der Path-Matrix wird die erste Spalte der
     CombinedScore-Matrix uebernommen */
  for (row_index = 0; row_index < rows; row_index++)
  {
    path_matrix[row_index][0].score =
      combinedscore_matrix[row_index][0].matrix_score;
    path_matrix[row_index][0].path_frame = row_index;
  }

  /* Spaltenweise Berechnung des opt. Pfades */
  for (column_index = 1; column_index < contig_len; column_index++)
  {
    for (row_index = 0; row_index < rows; row_index++)
    {
      /* Zaehlvariable fuer die Zeile wird umgerechnet in den entsprechenden
         Leserahmen */
      current_frame = get_current_frame(row_index);
      /* Aufruf der Methode zum Berechnen der moeglichen Leserahmen anhand von
         aktuellem Leserahmen und der Query-DNA-Sequenz */
      compute_precursors(current_frame,
                         column_index,
                         precursors);

      /* der max-Wert der moeglichen Vorgaenger wird berechnet */
      for (precursor_index = 0;
           precursor_index < NUM_PRECURSORS
             && (precursors[precursor_index] != UNDEFINED);
           ++precursor_index)
      {
        /* aktueller Vorgaengerleserahmen - es gibt max. 3 moegliche
           Vorgaenger */
        precursors_frame = precursors[precursor_index];
        /* Vorgaengerleserahmen wird umgerechnet in die entsprechende
           Matrix-Zeile */
        precursors_row = get_matrix_row(precursors_frame);

        /* der DP-Algo umfasst 3 moegliche Faelle
           1. Fall: Wechsel vom Reversen- auf den Forward-Strang bzw.
           umgekehrt */
        if ((current_frame < 0 && precursors_frame > 0) ||
            (current_frame > 0 && precursors_frame < 0))
        {
            max_new = path_matrix[precursors_row][column_index-1].score +
                      combinedscore_matrix[row_index][column_index].matrix_score
                      + 2*q;
        }
        /* 2. Fall: Einfacher Wechsel des Leserahmens, also von + zu +
           bzw.- zu - */
        else if (current_frame != 0 && precursors_frame != current_frame)
        {
            max_new = path_matrix[precursors_row][column_index-1].score +
                      combinedscore_matrix[row_index][column_index].matrix_score
                      + q;
        }
        /* 3. Fall: Leserahmen wird beibehalten bzw. Wechsel von kodierend zu
           nicht-kodierend oder umgekehrt */
        else
        {
            max_new = path_matrix[precursors_row][column_index-1].score +
                      combinedscore_matrix[row_index][column_index]
                      .matrix_score;
        }

        /* Bestimmen des Max-Wertes der max. 3 Moeglichkeiten und Speichern der
           Zeile, von der der Max-Wert stammt */
        if (gt_double_compare(max_new, max_old) > 0)
        {
            max_old = max_new;
            maxpath_frame = precursors_row;
        }
      }

      /* Speichern des Max-Wertes und der "Vorgaenger"-Zeile;
         zuruecksetzen der Variablen */
      path_matrix[row_index][column_index].score      = max_old;
      path_matrix[row_index][column_index].path_frame = maxpath_frame;

      max_new = DBL_MIN;
      max_old = DBL_MIN;
      maxpath_frame = 0;
    }
  }

  /* Aufruf der Methode zur Genvorhersage */
  had_err = mg_compute_gene_prediction(combinedscore_matrix,
                                       path_matrix,
                                       contig_len,
                                       hit_information,
                                       parsestruct_ptr, err);

  gt_array2dim_delete(path_matrix);

  return had_err;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %r9, %r14
movq %rcx, %r13
movq %rdx, 0x48(%rsp)
movq %rsi, 0x68(%rsp)
movq %rdi, 0x20(%rsp)
movq %r8, 0x70(%rsp)
movsd 0x1b8(%r8), %xmm0
movsd %xmm0, 0x50(%rsp)
leaq 0xb5a77(%rip), %rbx     # 0x386684
pushq $0x38
popq %rdi
pushq $0x44
popq %r15
movq %rbx, %rsi
movl %r15d, %edx
callq 0x93160
movq %rax, %r12
imulq $0x7, %r13, %rdi
pushq $0x10
popq %rsi
movq %rbx, %rdx
movl %r15d, %ecx
callq 0x9334a
movq %r12, 0x10(%rsp)
movq %rax, (%r12)
pushq $0x1
popq %rax
movq %r13, 0x40(%rsp)
shlq $0x4, %r13
movq 0x10(%rsp), %rsi
cmpq $0x7, %rax
je 0x2d0c65
movq -0x8(%rsi,%rax,8), %rdx
addq %r13, %rdx
movq %rdx, (%rsi,%rax,8)
incq %rax
jmp 0x2d0c4e
testq %r14, %r14
je 0x2d0c7a
movq %r14, %rdi
callq 0x89eb7
testb %al, %al
jne 0x2d0f42
xorl %eax, %eax
movzwl %ax, %ecx
cmpq 0x48(%rsp), %rcx
jae 0x2d0cab
shll $0x3, %ecx
movq 0x20(%rsp), %rdx
movq (%rdx,%rcx), %rdx
movsd (%rdx), %xmm0
movq 0x10(%rsp), %rdx
movq (%rdx,%rcx), %rcx
movsd %xmm0, (%rcx)
movw %ax, 0x8(%rcx)
incl %eax
jmp 0x2d0c7c
movsd 0x15575(%rip), %xmm1    # 0x2e6228
pushq $0x1
popq %rsi
movsd 0x50(%rsp), %xmm0
addsd %xmm0, %xmm0
movsd %xmm0, 0x90(%rsp)
movq %r14, 0x88(%rsp)
cmpq 0x40(%rsp), %rsi
jae 0x2d0ee0
xorl %ecx, %ecx
movq %rsi, %rax
xorl %edx, %edx
pushq $0x3
popq %rdi
divq %rdi
leal 0x1(%rdx), %eax
movl %eax, 0x1c(%rsp)
notl %edx
movq %rdx, 0x80(%rsp)
movq %rsi, %rax
shlq $0x4, %rax
movq %rax, 0x28(%rsp)
movq %rsi, 0x78(%rsp)
imulq $0x18, %rsi, %rax
movq %rax, 0x58(%rsp)
cmpw 0x48(%rsp), %cx
jae 0x2d0ed3
movsd %xmm1, (%rsp)
movzwl %cx, %edi
movq %rdi, 0x30(%rsp)
callq 0x2cf195
movl %eax, %r15d
testw %ax, %ax
je 0x2d0d5a
movl %r15d, %eax
negw %ax
cmovsw %r15w, %ax
cmpw 0x1c(%rsp), %ax
jne 0x2d0d6f
movl %r15d, %eax
negl %eax
movw %r15w, 0xa(%rsp)
xorl %ecx, %ecx
jmp 0x2d0d7d
movl 0x1c(%rsp), %eax
movw %ax, 0xa(%rsp)
xorl %ecx, %ecx
movq 0x80(%rsp), %rax
jmp 0x2d0d7d
movw %r15w, 0xa(%rsp)
movw $0x9, %cx
movw $0x9, %ax
movsd (%rsp), %xmm0
movw %cx, 0xc(%rsp)
movw %ax, 0xe(%rsp)
xorl %ebp, %ebp
xorl %esi, %esi
cmpq $0x3, %rbp
je 0x2d0e9e
movswq 0xa(%rsp,%rbp,2), %r13
cmpq $0x9, %r13
je 0x2d0e9e
movl %esi, 0x3c(%rsp)
movsd %xmm0, (%rsp)
movl %r15d, %r14d
testw %r15w, %r15w
setg %r12b
sets %r15b
movq %r13, %rdi
callq 0x2cf14c
movl %eax, %ebx
testw %r13w, %r13w
setg %dl
sets %cl
movzwl %ax, %eax
testb %dl, %r15b
jne 0x2d0e2b
andb %cl, %r12b
jne 0x2d0e2b
movq 0x10(%rsp), %rcx
movq (%rcx,%rax,8), %rax
movq 0x28(%rsp), %rcx
movsd -0x10(%rax,%rcx), %xmm0
movq 0x20(%rsp), %rax
movq 0x30(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x58(%rsp), %rcx
addsd (%rax,%rcx), %xmm0
movl %r14d, %r15d
testw %r15w, %r15w
je 0x2d0e97
cmpw %r15w, %r13w
movsd (%rsp), %xmm1
je 0x2d0e68
addsd 0x50(%rsp), %xmm0
jmp 0x2d0e68
movq 0x10(%rsp), %rcx
movq (%rcx,%rax,8), %rax
movq 0x28(%rsp), %rcx
movsd -0x10(%rax,%rcx), %xmm0
movq 0x20(%rsp), %rax
movq 0x30(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq 0x58(%rsp), %rcx
addsd (%rax,%rcx), %xmm0
addsd 0x90(%rsp), %xmm0
movsd (%rsp), %xmm1
movl %r14d, %r15d
movsd %xmm0, 0x60(%rsp)
movsd 0x60(%rsp), %xmm0
callq 0x955a7
movsd 0x60(%rsp), %xmm0
testl %eax, %eax
movl 0x3c(%rsp), %esi
cmovgl %ebx, %esi
jg 0x2d0e8f
movsd (%rsp), %xmm0
incq %rbp
jmp 0x2d0d90
movsd (%rsp), %xmm1
jmp 0x2d0e68
movq 0x10(%rsp), %rax
movq 0x30(%rsp), %rdx
movq (%rax,%rdx,8), %rax
movq 0x28(%rsp), %rcx
movsd %xmm0, (%rax,%rcx)
movw %si, 0x8(%rax,%rcx)
leal 0x1(%rdx), %ecx
movsd 0x1c2fa(%rip), %xmm1    # 0x2ed1c0
movq 0x88(%rsp), %r14
jmp 0x2d0d14
movq 0x78(%rsp), %rsi
incq %rsi
jmp 0x2d0cd1
movq 0x20(%rsp), %rdi
movq 0x10(%rsp), %r12
movq %r12, %rsi
movq 0x40(%rsp), %rdx
movq 0x68(%rsp), %rcx
movq 0x70(%rsp), %r8
movq %r14, %r9
callq 0x2cf2c0
movl %eax, %ebx
movq (%r12), %rdi
leaq 0xb5773(%rip), %r15     # 0x386684
movq %r15, %rsi
movl $0xa2, %edx
callq 0x936f9
movq %r12, %rdi
movq %r15, %rsi
movl $0xa2, %edx
callq 0x936f9
movl %ebx, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x16701f(%rip), %rax    # 0x437f68
movq (%rax), %rdi
leaq 0x140c0(%rip), %rsi     # 0x2e5013
leaq 0x14265(%rip), %rdx     # 0x2e51bf
leaq 0xb573d(%rip), %rcx     # 0x38669e
leaq 0xb571c(%rip), %r8      # 0x386684
pushq $0x46
popq %r9
xorl %eax, %eax
callq 0x17a50
callq 0x17390