// File: /workspace/github_c_makefile_star2_O0/genometools[P]genometools/src/extended/cds_check_visitor.c
// Function: check_cds_phases
static int check_cds_phases(GtArray *cds_features, GtCDSCheckVisitor *v,
                            bool is_multi, bool second_pass, GtError *err)
{
  GtPhase correct_phase = GT_PHASE_ZERO;
  GtFeatureNode *fn;
  GtStrand strand;
  bool first = true;
  GtUword i,
          total_length = 0;
  int had_err = 0;
  gt_error_check(err);
  gt_assert(cds_features);
  gt_assert(gt_array_size(cds_features));
  fn = *(GtFeatureNode**) gt_array_get_first(cds_features);
  strand = gt_feature_node_get_strand(fn);
  if (strand == GT_STRAND_REVERSE)
    gt_array_reverse(cds_features);
  for (i = 0; !had_err && i < gt_array_size(cds_features); i++) {
    fn = *(GtFeatureNode**) gt_array_get(cds_features, i);
    /* the first phase can be anything (except being undefined), because the
       GFF3 spec says:

       NOTE 4 - CDS features MUST have have a defined phase field. Otherwise it
       is not possible to infer the correct polypeptides corresponding to
       partially annotated genes. */
    if ((!i && gt_feature_node_get_phase(fn) == GT_PHASE_UNDEFINED) ||
        (i && gt_feature_node_get_phase(fn) != correct_phase)) {
      if (gt_hashmap_get(v->cds_features, fn)) {
        if (v->tidy && !is_multi && !gt_feature_node_has_children(fn)) {
          /* we can split the feature */
          gt_warning("%s feature on line %u in file \"%s\" has multiple "
                     "parents which require different phases; split feature",
                     gt_ft_CDS,
                     gt_genome_node_get_line_number((GtGenomeNode*) fn),
                     gt_genome_node_get_filename((GtGenomeNode*) fn));
          gt_hashmap_add(v->cds_features_to_split, fn, fn);
          v->splitting_is_necessary = true; /* split later */
        }
        else {
          gt_error_set(err, "%s feature on line %u in file \"%s\" has multiple "
                       "parents which require different phases",
                       gt_ft_CDS,
                       gt_genome_node_get_line_number((GtGenomeNode*) fn),
                       gt_genome_node_get_filename((GtGenomeNode*) fn));
          had_err = -1;
        }
      }
      else {
        if (v->tidy) {
          if (!second_pass) {
            gt_warning("%s feature on line %u in file \"%s\" has the wrong "
                       "phase %c -> correcting it to %c", gt_ft_CDS,
                       gt_genome_node_get_line_number((GtGenomeNode*) fn),
                       gt_genome_node_get_filename((GtGenomeNode*) fn),
                       GT_PHASE_CHARS[gt_feature_node_get_phase(fn)],
                       GT_PHASE_CHARS[correct_phase]);
          }
          gt_feature_node_set_phase(fn, correct_phase);
        }
        else {
          gt_error_set(err, "%s feature on line %u in file \"%s\" has the "
                       "wrong phase %c (should be %c)", gt_ft_CDS,
                       gt_genome_node_get_line_number((GtGenomeNode*) fn),
                       gt_genome_node_get_filename((GtGenomeNode*) fn),
                       GT_PHASE_CHARS[gt_feature_node_get_phase(fn)],
                       GT_PHASE_CHARS[correct_phase]);
          had_err = -1;
        }
      }
    }
    if (!had_err) {
      GtUword current_length = gt_genome_node_get_length((GtGenomeNode*) fn);
      if (first) {
        /* this handles the case of 5' partial genes, where CDS might not start
           on codon boundaries */
        GtUword current_phase = (GtUword) gt_feature_node_get_phase(fn);
        if (current_length >= current_phase) {
          /* we simply skip the amount of bases defined by phase */
          current_length -= current_phase;
          first = false;
          total_length = current_length;
          correct_phase = (3 - (total_length) % 3) % 3;
        } else {
          /* corner case: first CDS is single base */
          gt_assert(current_length == 1 && current_phase == 2);
          correct_phase = 1;
        }
      } else {
        total_length += current_length;
        correct_phase = (3 - (total_length) % 3) % 3;
      }
      gt_hashmap_add(v->cds_features, fn, fn); /* record CDS feature */
    }
  }
  return had_err;
}

// Assembly:
subq $0xb8, %rsp
movb %cl, %al
movb %dl, %cl
movq %rdi, 0xb0(%rsp)
movq %rsi, 0xa8(%rsp)
andb $0x1, %cl
movb %cl, 0xa7(%rsp)
andb $0x1, %al
movb %al, 0xa6(%rsp)
movq %r8, 0x98(%rsp)
movl $0x0, 0x94(%rsp)
movb $0x1, 0x83(%rsp)
movq $0x0, 0x70(%rsp)
movl $0x0, 0x6c(%rsp)
cmpq $0x0, 0x98(%rsp)
je 0xa51f0
movq 0x98(%rsp), %rdi
callq 0xc270
testb $0x1, %al
jne 0xa51b8
jmp 0xa51f0
movq 0x10ee19(%rip), %rax    # 0x1b3fd8
movq (%rax), %rdi
leaq 0xb8e9d(%rip), %rsi     # 0x15e066
leaq 0xb9478(%rip), %rdx     # 0x15e648
leaq 0xcd05f(%rip), %rcx     # 0x172236
leaq 0xccff2(%rip), %r8      # 0x1721d0
movl $0x31, %r9d
movb $0x0, %al
callq 0xb890
callq 0xb2e0
jmp 0xa51f2
jmp 0xa51f4
cmpq $0x0, 0xb0(%rsp)
jne 0xa5237
movq 0x10edd2(%rip), %rax    # 0x1b3fd8
movq (%rax), %rdi
leaq 0xb8e56(%rip), %rsi     # 0x15e066
leaq 0xcd1f8(%rip), %rdx     # 0x17240f
leaq 0xcd018(%rip), %rcx     # 0x172236
leaq 0xccfab(%rip), %r8      # 0x1721d0
movl $0x32, %r9d
movb $0x0, %al
callq 0xb890
callq 0xb2e0
jmp 0xa5239
jmp 0xa523b
movq 0xb0(%rsp), %rdi
callq 0x76490
cmpq $0x0, %rax
jne 0xa5286
movq 0x10ed83(%rip), %rax    # 0x1b3fd8
movq (%rax), %rdi
leaq 0xb8e07(%rip), %rsi     # 0x15e066
leaq 0xe8eb1(%rip), %rdx     # 0x18e117
leaq 0xccfc9(%rip), %rcx     # 0x172236
leaq 0xccf5c(%rip), %r8      # 0x1721d0
movl $0x33, %r9d
movb $0x0, %al
callq 0xb890
callq 0xb2e0
jmp 0xa5288
movq 0xb0(%rsp), %rdi
callq 0x75d00
movq (%rax), %rax
movq %rax, 0x88(%rsp)
movq 0x88(%rsp), %rdi
callq 0x20a10
movl %eax, 0x84(%rsp)
cmpl $0x1, 0x84(%rsp)
jne 0xa52cb
movq 0xb0(%rsp), %rdi
callq 0x76060
movq $0x0, 0x78(%rsp)
xorl %eax, %eax
cmpl $0x0, 0x6c(%rsp)
movb %al, 0x57(%rsp)
jne 0xa530a
movq 0x78(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0xb0(%rsp), %rdi
callq 0x76490
movq %rax, %rcx
movq 0x48(%rsp), %rax
cmpq %rcx, %rax
setb %al
movb %al, 0x57(%rsp)
movb 0x57(%rsp), %al
testb $0x1, %al
jne 0xa5317
jmp 0xa5724
movq 0xb0(%rsp), %rdi
movq 0x78(%rsp), %rsi
callq 0x75c80
movq (%rax), %rax
movq %rax, 0x88(%rsp)
cmpq $0x0, 0x78(%rsp)
jne 0xa534e
movq 0x88(%rsp), %rdi
callq 0x21f60
cmpl $0x3, %eax
je 0xa5374
cmpq $0x0, 0x78(%rsp)
je 0xa55c1
movq 0x88(%rsp), %rdi
callq 0x21f60
cmpl 0x94(%rsp), %eax
je 0xa55c1
movq 0xa8(%rsp), %rax
movq 0x10(%rax), %rdi
movq 0x88(%rsp), %rsi
callq 0x86470
cmpq $0x0, %rax
je 0xa5486
movq 0xa8(%rsp), %rax
testb $0x1, 0x20(%rax)
je 0xa542d
testb $0x1, 0xa7(%rsp)
jne 0xa542d
movq 0x88(%rsp), %rdi
callq 0x21140
testb $0x1, %al
jne 0xa542d
movq 0x88(%rsp), %rdi
callq 0x25850
movl %eax, 0x44(%rsp)
movq 0x88(%rsp), %rdi
callq 0x257c0
movl 0x44(%rsp), %edx
movq %rax, %rcx
leaq 0xcce57(%rip), %rdi     # 0x172247
leaq 0xbce44(%rip), %rsi     # 0x16223b
movb $0x0, %al
callq 0x1c550
movq 0xa8(%rsp), %rax
movq 0x18(%rax), %rdi
movq 0x88(%rsp), %rsi
movq 0x88(%rsp), %rdx
callq 0x86510
movq 0xa8(%rsp), %rax
movb $0x1, 0x21(%rax)
jmp 0xa5481
movq 0x98(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x88(%rsp), %rdi
callq 0x25850
movl %eax, 0x40(%rsp)
movq 0x88(%rsp), %rdi
callq 0x257c0
movq 0x38(%rsp), %rdi
movl 0x40(%rsp), %ecx
movq %rax, %r8
leaq 0xcce42(%rip), %rsi     # 0x1722ad
leaq 0xbcdc9(%rip), %rdx     # 0x16223b
movb $0x0, %al
callq 0xc0d0
movl $0xffffffff, 0x6c(%rsp) # imm = 0xFFFFFFFF
jmp 0xa55bf
movq 0xa8(%rsp), %rax
testb $0x1, 0x20(%rax)
je 0xa552e
testb $0x1, 0xa6(%rsp)
jne 0xa5515
movq 0x88(%rsp), %rdi
callq 0x25850
movl %eax, 0x2c(%rsp)
movq 0x88(%rsp), %rdi
callq 0x257c0
movq %rax, 0x30(%rsp)
movq 0x88(%rsp), %rdi
callq 0x21f60
movl 0x2c(%rsp), %edx
movq 0x30(%rsp), %rcx
movl %eax, %eax
movl %eax, %esi
leaq 0xba6fa(%rip), %rax     # 0x15fbe0
movsbl (%rax,%rsi), %r8d
movl 0x94(%rsp), %eax
movl %eax, %esi
leaq 0xba6e5(%rip), %rax     # 0x15fbe0
movsbl (%rax,%rsi), %r9d
leaq 0xccdfd(%rip), %rdi     # 0x172304
leaq 0xbcd2d(%rip), %rsi     # 0x16223b
movb $0x0, %al
callq 0x1c550
movq 0x88(%rsp), %rdi
movl 0x94(%rsp), %esi
callq 0x1fff0
jmp 0xa55bd
movq 0x98(%rsp), %rax
movq %rax, 0x10(%rsp)
movq 0x88(%rsp), %rdi
callq 0x25850
movl %eax, 0x1c(%rsp)
movq 0x88(%rsp), %rdi
callq 0x257c0
movq %rax, 0x20(%rsp)
movq 0x88(%rsp), %rdi
callq 0x21f60
movq 0x10(%rsp), %rdi
movl 0x1c(%rsp), %ecx
movq 0x20(%rsp), %r8
movl %eax, %eax
movl %eax, %edx
leaq 0xba65c(%rip), %rax     # 0x15fbe0
movsbl (%rax,%rdx), %r9d
movl 0x94(%rsp), %eax
movl %eax, %edx
leaq 0xba647(%rip), %rax     # 0x15fbe0
movsbl (%rax,%rdx), %eax
leaq 0xccdb1(%rip), %rsi     # 0x172355
leaq 0xbcc90(%rip), %rdx     # 0x16223b
movl %eax, (%rsp)
movb $0x0, %al
callq 0xc0d0
movl $0xffffffff, 0x6c(%rsp) # imm = 0xFFFFFFFF
jmp 0xa55bf
jmp 0xa55c1
cmpl $0x0, 0x6c(%rsp)
jne 0xa570f
movq 0x88(%rsp), %rdi
callq 0x25ab0
movq %rax, 0x60(%rsp)
testb $0x1, 0x83(%rsp)
je 0xa56b5
movq 0x88(%rsp), %rdi
callq 0x21f60
movl %eax, %eax
movq %rax, 0x58(%rsp)
movq 0x60(%rsp), %rax
cmpq 0x58(%rsp), %rax
jb 0xa565c
movq 0x58(%rsp), %rcx
movq 0x60(%rsp), %rax
subq %rcx, %rax
movq %rax, 0x60(%rsp)
movb $0x0, 0x83(%rsp)
movq 0x60(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
movl $0x3, %eax
subq %rdx, %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
movl %edx, %eax
movl %eax, 0x94(%rsp)
jmp 0xa56b3
jmp 0xa565e
cmpq $0x1, 0x60(%rsp)
jne 0xa566e
cmpq $0x2, 0x58(%rsp)
je 0xa56a6
movq 0x10e963(%rip), %rax    # 0x1b3fd8
movq (%rax), %rdi
leaq 0xb89e7(%rip), %rsi     # 0x15e066
leaq 0xccd18(%rip), %rdx     # 0x17239e
leaq 0xccba9(%rip), %rcx     # 0x172236
leaq 0xccb3c(%rip), %r8      # 0x1721d0
movl $0x7b, %r9d
movb $0x0, %al
callq 0xb890
callq 0xb2e0
jmp 0xa56a8
movl $0x1, 0x94(%rsp)
jmp 0xa56ee
movq 0x60(%rsp), %rax
addq 0x70(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x70(%rsp), %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
movl $0x3, %eax
subq %rdx, %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
movl %edx, %eax
movl %eax, 0x94(%rsp)
movq 0xa8(%rsp), %rax
movq 0x10(%rax), %rdi
movq 0x88(%rsp), %rsi
movq 0x88(%rsp), %rdx
callq 0x86510
jmp 0xa5711
movq 0x78(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x78(%rsp)
jmp 0xa52d4
movl 0x6c(%rsp), %eax
addq $0xb8, %rsp
retq