// File: /workspace/github_c_makefile_star2_O1/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, 0x28(%rsp)
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, 0x60(%rsp)
movq %rdi, 0x20(%rsp)
movq %r8, 0x68(%rsp)
movsd 0x1b8(%r8), %xmm0
movsd %xmm0, 0x58(%rsp)
leaq 0xb5cbf(%rip), %rbx     # 0x3efa94
movl $0x38, %edi
movq %rbx, %rsi
movl $0x44, %edx
callq 0x1092b2
movq %rax, %r12
leaq (,%r14,8), %rdi
subq %r14, %rdi
movl $0x10, %esi
movq %rbx, %rdx
movl $0x44, %ecx
callq 0x1093ef
movq %rax, (%r12)
movq %r14, 0x30(%rsp)
shlq $0x4, %r14
addq %r14, %rax
movl $0x1, %edx
movq %rax, (%r12,%rdx,8)
incq %rdx
addq %r14, %rax
cmpq $0x7, %rdx
jne 0x339e1c
cmpq $0x0, 0x28(%rsp)
je 0x339e46
movq 0x28(%rsp), %rdi
callq 0x101a9a
testb %al, %al
jne 0x33a13e
testq %r15, %r15
movq 0x20(%rsp), %rbx
je 0x339e71
xorl %eax, %eax
movq (%rbx,%rax,8), %rcx
movsd (%rcx), %xmm0
movq (%r12,%rax,8), %rcx
movsd %xmm0, (%rcx)
movw %ax, 0x8(%rcx)
incq %rax
movzwl %ax, %ecx
cmpq %r15, %rcx
jb 0x339e52
cmpq $0x2, 0x30(%rsp)
jb 0x33a0e1
movl $0x1, %ecx
movsd 0x1539e(%rip), %xmm1    # 0x34f228
movsd 0x58(%rsp), %xmm0
addsd %xmm0, %xmm0
movsd %xmm0, 0x88(%rsp)
movq %r15, 0x80(%rsp)
testq %r15, %r15
je 0x33a0d3
movq %rcx, %rax
movabsq $-0x5555555555555555, %rdx # imm = 0xAAAAAAAAAAAAAAAB
mulq %rdx
shrl %edx
leal (%rdx,%rdx,2), %eax
movl %ecx, %edx
subl %eax, %edx
leal 0x1(%rdx), %eax
movl %eax, 0x18(%rsp)
notl %edx
movq %rdx, 0x78(%rsp)
xorl %r14d, %r14d
movq %rcx, %rax
shlq $0x4, %rax
movq %rax, 0x48(%rsp)
movq %rcx, 0x70(%rsp)
leaq (%rcx,%rcx,2), %rax
movq %rax, 0x38(%rsp)
xorl %eax, %eax
movl %eax, 0x50(%rsp)
movsd %xmm1, 0x10(%rsp)
movq %r14, %rdi
callq 0x338258
movl %eax, %ecx
testw %ax, %ax
je 0x339f34
movl %ecx, %eax
negw %ax
cmovsw %cx, %ax
cmpw 0x18(%rsp), %ax
jne 0x339f50
movl %ecx, %eax
negl %eax
movw %cx, 0xa(%rsp)
movw $0x0, 0xc(%rsp)
movw %ax, 0xe(%rsp)
jmp 0x339f5d
movl 0x18(%rsp), %eax
movw %ax, 0xa(%rsp)
movw $0x0, 0xc(%rsp)
movq 0x78(%rsp), %rax
movw %ax, 0xe(%rsp)
jmp 0x339f5d
movw %cx, 0xa(%rsp)
movl $0x90009, 0xc(%rsp)     # imm = 0x90009
movsd 0x10(%rsp), %xmm0
xorl %ebp, %ebp
xorl %edx, %edx
movq %r14, 0x40(%rsp)
movl %ecx, 0x1c(%rsp)
movswq 0xa(%rsp,%rbp,2), %r13
cmpq $0x9, %r13
je 0x33a08c
movl %edx, 0x54(%rsp)
movsd %xmm0, 0x10(%rsp)
movq %r12, %r14
testw %cx, %cx
setg %bl
sets %r12b
movq %r13, %rdi
callq 0x338240
movl %eax, %r15d
testw %r13w, %r13w
setg %dl
sets %cl
movzwl %ax, %eax
testb %dl, %r12b
jne 0x339ff9
andb %cl, %bl
jne 0x339ff9
movq %r14, %r12
movq (%r14,%rax,8), %rax
movq 0x48(%rsp), %rcx
movsd -0x10(%rax,%rcx), %xmm0
movl 0x1c(%rsp), %eax
testw %ax, %ax
je 0x33a02e
cmpw %ax, %r13w
je 0x33a02e
movq 0x20(%rsp), %rbx
movq 0x40(%rsp), %r14
movq (%rbx,%r14,8), %rax
movq 0x38(%rsp), %rcx
addsd (%rax,%rcx,8), %xmm0
addsd 0x58(%rsp), %xmm0
jmp 0x33a046
movq %r14, %r12
movq (%r14,%rax,8), %rax
movq 0x48(%rsp), %rcx
movsd -0x10(%rax,%rcx), %xmm0
movq 0x20(%rsp), %rbx
movq 0x40(%rsp), %r14
movq (%rbx,%r14,8), %rax
movq 0x38(%rsp), %rcx
addsd (%rax,%rcx,8), %xmm0
addsd 0x88(%rsp), %xmm0
jmp 0x33a046
movq 0x20(%rsp), %rbx
movq 0x40(%rsp), %r14
movq (%rbx,%r14,8), %rax
movq 0x38(%rsp), %rcx
addsd (%rax,%rcx,8), %xmm0
movsd 0x10(%rsp), %xmm1
movsd %xmm0, 0x90(%rsp)
callq 0x10acd4
movsd 0x90(%rsp), %xmm1
testl %eax, %eax
movl 0x54(%rsp), %edx
cmovgl %r15d, %edx
jg 0x33a075
movsd 0x10(%rsp), %xmm1
incq %rbp
movapd %xmm1, %xmm0
cmpq $0x3, %rbp
movl 0x1c(%rsp), %ecx
jne 0x339f70
jmp 0x33a090
movapd %xmm0, %xmm1
movq (%r12,%r14,8), %rax
movq 0x48(%rsp), %rcx
movsd %xmm1, (%rax,%rcx)
movw %dx, 0x8(%rax,%rcx)
movl 0x50(%rsp), %eax
incl %eax
movzwl %ax, %r14d
movsd 0x1c13b(%rip), %xmm1    # 0x3561f0
movq 0x80(%rsp), %r15
cmpq %r15, %r14
jb 0x339ef4
movsd 0x1c122(%rip), %xmm1    # 0x3561f0
movq 0x70(%rsp), %rcx
incq %rcx
cmpq 0x30(%rsp), %rcx
jne 0x339ea5
movq %rbx, %rdi
movq %r12, %rsi
movq 0x30(%rsp), %rdx
movq 0x60(%rsp), %rcx
movq 0x68(%rsp), %r8
movq 0x28(%rsp), %r9
callq 0x338350
movl %eax, %ebx
movq (%r12), %rdi
leaq 0xb5987(%rip), %r15     # 0x3efa94
movq %r15, %rsi
movl $0xa2, %edx
callq 0x109670
movq %r12, %rdi
movq %r15, %rsi
movl $0xa2, %edx
callq 0x109670
movl %ebx, %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x97f82
nop