// File: /workspace/github_c_makefile_star2_O0/genometools[P]genometools/src/extended/hmm.c
// Function: gt_hmm_decode
void gt_hmm_decode(const GtHMM *hmm,
                unsigned int *state_sequence,
                const unsigned int *emissions,
                unsigned int num_of_emissions)
{
  double **max_probabilities, tmp_prob;
  unsigned int **backtrace, colidx, precolidx, emission;
  int row, column, num_of_rows, num_of_columns, previous_row;

  gt_assert(hmm);
  gt_assert(gt_hmm_is_valid(hmm));
  gt_assert(num_of_emissions);

  /* alloc tables */
  num_of_rows = hmm->num_of_states;
  num_of_columns = num_of_emissions;
  gt_array2dim_malloc(max_probabilities, num_of_rows, 2);
  gt_array2dim_malloc(backtrace, num_of_rows, num_of_columns);

  /* fill DP table */
  for (row = 0; row < num_of_rows; row++) { /* first column */
    if (emissions[0] == GT_WILDCARD)
      emission = hmm->num_of_symbols - 1;
    else
      emission = emissions[0];
    gt_assert(emission < hmm->num_of_symbols);
    max_probabilities[row][0] = hmm->initial_state_prob[row] +
                                hmm->emission_prob[row][emission];
    backtrace[row][0] = row;
  }

  for (column = 1; column < num_of_columns; column++) { /* other columns */
    if (emissions[column] == GT_WILDCARD)
      emission = hmm->num_of_symbols - 1;
    else
      emission = emissions[column];
    gt_assert(emission < hmm->num_of_symbols);
    colidx = column & 1;
    precolidx = (column - 1) & 1;
    for (row = 0; row < num_of_rows; row++) {
      max_probabilities[row][colidx] = max_probabilities[0][precolidx] +
                                     hmm->transition_prob[0][row] +
                                     hmm->emission_prob[row][emission];
      backtrace[row][column] = 0;
      for (previous_row = 1; previous_row < num_of_rows; previous_row++) {
        tmp_prob = max_probabilities[previous_row][precolidx] +
                   hmm->transition_prob[previous_row][row] +
                   hmm->emission_prob[row][emission];
        if (tmp_prob - max_probabilities[row][colidx] > DBL_EPSILON) {
          max_probabilities[row][colidx] = tmp_prob;
          backtrace[row][column] = previous_row;
        }
      }
    }
  }

  /* backtracing, determine end state with maximum probability */
  colidx = (num_of_columns - 1) & 1;
  tmp_prob = max_probabilities[0][colidx];
  state_sequence[num_of_columns - 1] = 0;
  for (row = 1; row < num_of_rows; row++) {
    if (max_probabilities[row][colidx] - tmp_prob > DBL_EPSILON)
      state_sequence[num_of_columns - 1] = row;
  }

  /* backtracing, follow the links */
  for (column = num_of_columns - 2; column >= 0; column--)
    state_sequence[column] = backtrace[state_sequence[column + 1]][column + 1];

  /* free tables */
  gt_array2dim_delete(backtrace);
  gt_array2dim_delete(max_probabilities);
}

// Assembly:
subq $0x68, %rsp
movq %rdi, 0x60(%rsp)
movq %rsi, 0x58(%rsp)
movq %rdx, 0x50(%rsp)
movl %ecx, 0x4c(%rsp)
cmpq $0x0, 0x60(%rsp)
jne 0x18b947
movq 0x4b068a(%rip), %rax    # 0x63bfa0
movq (%rax), %rdi
leaq 0x38a6f3(%rip), %rsi    # 0x516013
leaq 0x38ea8f(%rip), %rdx    # 0x51a3b6
leaq 0x3c9d19(%rip), %rcx    # 0x555647
leaq 0x3c9b26(%rip), %r8     # 0x55545b
movl $0x138, %r9d            # imm = 0x138
movb $0x0, %al
callq 0x199f0
callq 0x19370
jmp 0x18b949
jmp 0x18b94b
movq 0x60(%rsp), %rdi
callq 0x18b260
testb $0x1, %al
jne 0x18b991
movq 0x4b0640(%rip), %rax    # 0x63bfa0
movq (%rax), %rdi
leaq 0x38a6a9(%rip), %rsi    # 0x516013
leaq 0x3c9cc1(%rip), %rdx    # 0x555632
leaq 0x3c9ccf(%rip), %rcx    # 0x555647
leaq 0x3c9adc(%rip), %r8     # 0x55545b
movl $0x139, %r9d            # imm = 0x139
movb $0x0, %al
callq 0x199f0
callq 0x19370
jmp 0x18b993
jmp 0x18b995
cmpl $0x0, 0x4c(%rsp)
jne 0x18b9d4
movq 0x4b05fd(%rip), %rax    # 0x63bfa0
movq (%rax), %rdi
leaq 0x38a666(%rip), %rsi    # 0x516013
leaq 0x3ca324(%rip), %rdx    # 0x555cd8
leaq 0x3c9c8c(%rip), %rcx    # 0x555647
leaq 0x3c9a99(%rip), %r8     # 0x55545b
movl $0x13a, %r9d            # imm = 0x13A
movb $0x0, %al
callq 0x199f0
callq 0x19370
jmp 0x18b9d6
movq 0x60(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x18(%rsp)
movl 0x4c(%rsp), %eax
movl %eax, 0x14(%rsp)
movslq 0x18(%rsp), %rdi
shlq $0x3, %rdi
leaq 0x3c9a62(%rip), %rsi    # 0x55545b
movl $0x13f, %edx            # imm = 0x13F
callq 0xe80f0
movq %rax, 0x40(%rsp)
movslq 0x18(%rsp), %rdi
shlq $0x3, %rdi
shlq %rdi
leaq 0x3c9a40(%rip), %rsi    # 0x55545b
movl $0x13f, %edx            # imm = 0x13F
callq 0xe80f0
movq %rax, %rcx
movq 0x40(%rsp), %rax
movq %rcx, (%rax)
movq $0x1, 0x8(%rsp)
movq 0x8(%rsp), %rax
movslq 0x18(%rsp), %rcx
cmpq %rcx, %rax
jae 0x18ba7c
movq 0x40(%rsp), %rax
movq 0x8(%rsp), %rcx
subq $0x1, %rcx
movq (%rax,%rcx,8), %rdx
addq $0x10, %rdx
movq 0x40(%rsp), %rax
movq 0x8(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movq 0x8(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x8(%rsp)
jmp 0x18ba39
movslq 0x18(%rsp), %rdi
shlq $0x3, %rdi
leaq 0x3c99cf(%rip), %rsi    # 0x55545b
movl $0x140, %edx            # imm = 0x140
callq 0xe80f0
movq %rax, 0x30(%rsp)
movslq 0x18(%rsp), %rdi
shlq $0x2, %rdi
movslq 0x14(%rsp), %rax
imulq %rax, %rdi
leaq 0x3c99a7(%rip), %rsi    # 0x55545b
movl $0x140, %edx            # imm = 0x140
callq 0xe80f0
movq %rax, %rcx
movq 0x30(%rsp), %rax
movq %rcx, (%rax)
movq $0x1, (%rsp)
movq (%rsp), %rax
movslq 0x18(%rsp), %rcx
cmpq %rcx, %rax
jae 0x18bb17
movq 0x30(%rsp), %rax
movq (%rsp), %rcx
subq $0x1, %rcx
movq (%rax,%rcx,8), %rdx
movslq 0x14(%rsp), %rax
shlq $0x2, %rax
addq %rax, %rdx
movq 0x30(%rsp), %rax
movq (%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movq (%rsp), %rax
addq $0x1, %rax
movq %rax, (%rsp)
jmp 0x18bad1
movl $0x0, 0x20(%rsp)
movl 0x20(%rsp), %eax
cmpl 0x18(%rsp), %eax
jge 0x18bc04
movq 0x50(%rsp), %rax
cmpl $0xfe, (%rax)
jne 0x18bb4b
movq 0x60(%rsp), %rax
movl 0x4(%rax), %eax
subl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x18bb56
movq 0x50(%rsp), %rax
movl (%rax), %eax
movl %eax, 0x24(%rsp)
jmp 0x18bb58
movl 0x24(%rsp), %eax
movq 0x60(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jb 0x18bb9e
movq 0x4b0433(%rip), %rax    # 0x63bfa0
movq (%rax), %rdi
leaq 0x38a49c(%rip), %rsi    # 0x516013
leaq 0x3c9ad7(%rip), %rdx    # 0x555655
leaq 0x3c9ac2(%rip), %rcx    # 0x555647
leaq 0x3c98cf(%rip), %r8     # 0x55545b
movl $0x148, %r9d            # imm = 0x148
movb $0x0, %al
callq 0x199f0
callq 0x19370
jmp 0x18bba0
movq 0x60(%rsp), %rax
movq 0x8(%rax), %rax
movslq 0x20(%rsp), %rcx
movsd (%rax,%rcx,8), %xmm0
movq 0x60(%rsp), %rax
movq 0x18(%rax), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x24(%rsp), %ecx
addsd (%rax,%rcx,8), %xmm0
movq 0x40(%rsp), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movsd %xmm0, (%rax)
movl 0x20(%rsp), %ecx
movq 0x30(%rsp), %rax
movslq 0x20(%rsp), %rdx
movq (%rax,%rdx,8), %rax
movl %ecx, (%rax)
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
jmp 0x18bb1f
movl $0x1, 0x1c(%rsp)
movl 0x1c(%rsp), %eax
cmpl 0x14(%rsp), %eax
jge 0x18be3d
movq 0x50(%rsp), %rax
movslq 0x1c(%rsp), %rcx
cmpl $0xfe, (%rax,%rcx,4)
jne 0x18bc3e
movq 0x60(%rsp), %rax
movl 0x4(%rax), %eax
subl $0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x18bc4f
movq 0x50(%rsp), %rax
movslq 0x1c(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0x24(%rsp)
jmp 0x18bc51
movl 0x24(%rsp), %eax
movq 0x60(%rsp), %rcx
cmpl 0x4(%rcx), %eax
jb 0x18bc97
movq 0x4b033a(%rip), %rax    # 0x63bfa0
movq (%rax), %rdi
leaq 0x38a3a3(%rip), %rsi    # 0x516013
leaq 0x3c99de(%rip), %rdx    # 0x555655
leaq 0x3c99c9(%rip), %rcx    # 0x555647
leaq 0x3c97d6(%rip), %r8     # 0x55545b
movl $0x153, %r9d            # imm = 0x153
movb $0x0, %al
callq 0x199f0
callq 0x19370
jmp 0x18bc99
movl 0x1c(%rsp), %eax
andl $0x1, %eax
movl %eax, 0x2c(%rsp)
movl 0x1c(%rsp), %eax
subl $0x1, %eax
andl $0x1, %eax
movl %eax, 0x28(%rsp)
movl $0x0, 0x20(%rsp)
movl 0x20(%rsp), %eax
cmpl 0x18(%rsp), %eax
jge 0x18be2b
movq 0x40(%rsp), %rax
movq (%rax), %rax
movl 0x28(%rsp), %ecx
movsd (%rax,%rcx,8), %xmm0
movq 0x60(%rsp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rax
movslq 0x20(%rsp), %rcx
addsd (%rax,%rcx,8), %xmm0
movq 0x60(%rsp), %rax
movq 0x18(%rax), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x24(%rsp), %ecx
addsd (%rax,%rcx,8), %xmm0
movq 0x40(%rsp), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x2c(%rsp), %ecx
movsd %xmm0, (%rax,%rcx,8)
movq 0x30(%rsp), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0x1c(%rsp), %rcx
movl $0x0, (%rax,%rcx,4)
movl $0x1, 0x10(%rsp)
movl 0x10(%rsp), %eax
cmpl 0x18(%rsp), %eax
jge 0x18be19
movq 0x40(%rsp), %rax
movslq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x28(%rsp), %ecx
movsd (%rax,%rcx,8), %xmm0
movq 0x60(%rsp), %rax
movq 0x10(%rax), %rax
movslq 0x10(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0x20(%rsp), %rcx
addsd (%rax,%rcx,8), %xmm0
movq 0x60(%rsp), %rax
movq 0x18(%rax), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x24(%rsp), %ecx
addsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x38(%rsp)
movsd 0x38(%rsp), %xmm0
movq 0x40(%rsp), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x2c(%rsp), %ecx
subsd (%rax,%rcx,8), %xmm0
movsd 0x3c965e(%rip), %xmm1   # 0x555428
ucomisd %xmm1, %xmm0
jbe 0x18be07
movsd 0x38(%rsp), %xmm0
movq 0x40(%rsp), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x2c(%rsp), %ecx
movsd %xmm0, (%rax,%rcx,8)
movl 0x10(%rsp), %edx
movq 0x30(%rsp), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0x1c(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
jmp 0x18be09
movl 0x10(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x10(%rsp)
jmp 0x18bd43
jmp 0x18be1b
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
jmp 0x18bcba
jmp 0x18be2d
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x18bc0c
movl 0x14(%rsp), %eax
subl $0x1, %eax
andl $0x1, %eax
movl %eax, 0x2c(%rsp)
movq 0x40(%rsp), %rax
movq (%rax), %rax
movl 0x2c(%rsp), %ecx
movsd (%rax,%rcx,8), %xmm0
movsd %xmm0, 0x38(%rsp)
movq 0x58(%rsp), %rax
movl 0x14(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl $0x0, (%rax,%rcx,4)
movl $0x1, 0x20(%rsp)
movl 0x20(%rsp), %eax
cmpl 0x18(%rsp), %eax
jge 0x18beda
movq 0x40(%rsp), %rax
movslq 0x20(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x2c(%rsp), %ecx
movsd (%rax,%rcx,8), %xmm0
subsd 0x38(%rsp), %xmm0
movsd 0x3c9579(%rip), %xmm1   # 0x555428
ucomisd %xmm1, %xmm0
jbe 0x18becb
movl 0x20(%rsp), %edx
movq 0x58(%rsp), %rax
movl 0x14(%rsp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movl %edx, (%rax,%rcx,4)
jmp 0x18becd
movl 0x20(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x20(%rsp)
jmp 0x18be80
movl 0x14(%rsp), %eax
subl $0x2, %eax
movl %eax, 0x1c(%rsp)
cmpl $0x0, 0x1c(%rsp)
jl 0x18bf2e
movq 0x30(%rsp), %rax
movq 0x58(%rsp), %rcx
movl 0x1c(%rsp), %edx
addl $0x1, %edx
movslq %edx, %rdx
movl (%rcx,%rdx,4), %ecx
movq (%rax,%rcx,8), %rax
movl 0x1c(%rsp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movl (%rax,%rcx,4), %edx
movq 0x58(%rsp), %rax
movslq 0x1c(%rsp), %rcx
movl %edx, (%rax,%rcx,4)
movl 0x1c(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x18bee5
movq 0x30(%rsp), %rax
movq (%rax), %rdi
leaq 0x3c951e(%rip), %rsi    # 0x55545b
movl $0x175, %edx            # imm = 0x175
callq 0xe88c0
movq 0x30(%rsp), %rdi
leaq 0x3c9508(%rip), %rsi    # 0x55545b
movl $0x175, %edx            # imm = 0x175
callq 0xe88c0
movq 0x40(%rsp), %rax
movq (%rax), %rdi
leaq 0x3c94ef(%rip), %rsi    # 0x55545b
movl $0x176, %edx            # imm = 0x176
callq 0xe88c0
movq 0x40(%rsp), %rdi
leaq 0x3c94d9(%rip), %rsi    # 0x55545b
movl $0x176, %edx            # imm = 0x176
callq 0xe88c0
addq $0x68, %rsp
retq
nopw %cs:(%rax,%rax)