// File: /workspace/github_c_makefile_star2_O0/sheneman[P]clearcut/clearcut.c
// Function: main
int
main(int argc,
     char *argv[]) {

  DMAT *dmat;         /* The working distance matrix */
  DMAT *dmat_backup = NULL;/* A backup distance matrix    */
  NJ_TREE *tree;      /* The phylogenetic tree       */
  NJ_ARGS *nj_args;   /* Structure for holding command-line arguments */
  long int i;

  /* some variables for tracking time */
  struct timeval tv;
  unsigned long long startUs, endUs;
  

  /* check and parse supplied command-line arguments */
  nj_args = NJ_handle_args(argc, argv);
  if(!nj_args) {
    fprintf(stderr, "Clearcut: Error processing command-line arguments.\n");
    exit(-1);
  }

  /* for verbose reporting, print the random number seed to stdout */
  if(nj_args->verbose_flag) {
    printf("PRNG SEED: %d\n", nj_args->seed);
  }

  /* Initialize Mersenne Twister PRNG */
  init_genrand(nj_args->seed);


  switch(nj_args->input_mode) {

    /* If the input type is a distance matrix */
  case NJ_INPUT_MODE_DISTANCE:

    /* parse the distance matrix */
    dmat = NJ_parse_distance_matrix(nj_args);
    if(!dmat) {
      exit(-1);
    }

    break;

    /* If the input type is a multiple sequence alignment */
  case NJ_INPUT_MODE_ALIGNED_SEQUENCES:

    /* build a distance matrix from a multiple sequence alignment */
    dmat = NJ_build_distance_matrix(nj_args);
    if(!dmat) {
      fprintf(stderr, "Clearcut: Failed to build distance matrix from alignment.\n");
      exit(-1);
    }
    
    break;

  default:

    fprintf(stderr, "Clearcut: Could not determine how to process input\n");
    exit(-1);
  }

  /*
   * Output the computed distance matrix,
   *  if the user specified one.
   */
  if(nj_args->matrixout) {
    NJ_output_matrix(nj_args, dmat);
  }
  
  /* 
   * If we are going to generate multiple trees from
   * the same distance matrix, we need to make a backup 
   * of the original distance matrix.
   */
  if(nj_args->ntrees > 1) {
    dmat_backup = NJ_dup_dmat(dmat);
  }
  
  /* process n trees */
  for(i=0;i<nj_args->ntrees;i++) {
    
    /* 
     * If the user has specified matrix shuffling, we need 
     * to randomize the distance matrix
     */
    if(nj_args->shuffle) {
      NJ_shuffle_distance_matrix(dmat);
    }

    /* RECORD THE PRECISE TIME OF THE START OF THE NEIGHBOR-JOINING */
    gettimeofday(&tv, NULL);
    startUs = ((unsigned long long) tv.tv_sec * 1000000ULL)
      + ((unsigned long long) tv.tv_usec);

    
    /* 
     * Invoke either the Relaxed Neighbor-Joining algorithm (default)
     * or the "traditional" Neighbor-Joining algorithm 
     */
    if(nj_args->neighbor) {
      tree = NJ_neighbor_joining(nj_args, dmat);
    } else {
      tree = NJ_relaxed_nj(nj_args, dmat);
    }
  
    if(!tree) {
      fprintf(stderr, "Clearcut: Failed to construct tree.\n");
      exit(0);
    }

    /* RECORD THE PRECISE TIME OF THE END OF THE NEIGHBOR-JOINING */
    gettimeofday(&tv, NULL);
    endUs = ((unsigned long long) tv.tv_sec * 1000000ULL)
      + ((unsigned long long) tv.tv_usec);

    /* print the time taken to perform the neighbor join */
    if(nj_args->verbose_flag) {
      if(nj_args->neighbor) {
	fprintf(stderr, "NJ tree built in %llu.%06llu secs\n",
		(endUs - startUs) / 1000000ULL,
		(endUs - startUs) % 1000000ULL);
      } else { 
	fprintf(stderr, "RNJ tree built in %llu.%06llu secs\n",
		(endUs - startUs) / 1000000ULL,
		(endUs - startUs) % 1000000ULL);
      }
    }

    /* Output the neighbor joining tree here */
    NJ_output_tree(nj_args, tree, dmat, i);
    
    NJ_free_tree(tree);  /* Free the tree */
    NJ_free_dmat(dmat);  /* Free the working distance matrix */

    /* 
     * If we need to do another iteration, lets re-initialize 
     * our working distance matrix.
     */
    if(nj_args->ntrees > 1 && i<(nj_args->ntrees-1) ) {
      dmat = NJ_dup_dmat(dmat_backup);
    }
  }
  
  /* Free the backup distance matrix */
  if(nj_args->ntrees > 1) {
    NJ_free_dmat(dmat_backup);
  }

  /* If verbosity, describe where the tree output is */
  if(nj_args->verbose_flag) {
    if(nj_args->neighbor) {
      printf("NJ tree(s) in %s\n", nj_args->outfilename);
    } else {
      printf("Relaxed NJ tree(s) in %s\n", nj_args->outfilename);
    }
  }

  exit(0);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x0, -0x20(%rbp)
movl -0x8(%rbp), %edi
movq -0x10(%rbp), %rsi
callq 0x8270
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x2367
movq 0xccac(%rip), %rax      # 0xeff8
movq (%rax), %rdi
leaq 0x8cea(%rip), %rsi      # 0xb040
movb $0x0, %al
callq 0x2150
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x2200
movq -0x30(%rbp), %rax
cmpl $0x0, 0x20(%rax)
je 0x2386
movq -0x30(%rbp), %rax
movl 0x48(%rax), %esi
leaq 0x8cf5(%rip), %rdi      # 0xb074
movb $0x0, %al
callq 0x20e0
movq -0x30(%rbp), %rax
movslq 0x48(%rax), %rdi
callq 0x8da0
movq -0x30(%rbp), %rax
movl 0x18(%rax), %eax
movl %eax, -0x5c(%rbp)
subl $0x64, %eax
je 0x23ae
jmp 0x23a4
movl -0x5c(%rbp), %eax
subl $0x66, %eax
je 0x23ce
jmp 0x2406
movq -0x30(%rbp), %rdi
callq 0x64f0
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x23cc
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x2200
jmp 0x2428
movq -0x30(%rbp), %rdi
callq 0x52d0
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
jne 0x2404
movq 0xcc0f(%rip), %rax      # 0xeff8
movq (%rax), %rdi
leaq 0x8c90(%rip), %rsi      # 0xb083
movb $0x0, %al
callq 0x2150
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x2200
jmp 0x2428
movq 0xcbeb(%rip), %rax      # 0xeff8
movq (%rax), %rdi
leaq 0x8ca7(%rip), %rsi      # 0xb0be
movb $0x0, %al
callq 0x2150
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x2200
movq -0x30(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x2440
movq -0x30(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x70a0
movq -0x30(%rbp), %rax
cmpl $0x1, 0x5c(%rax)
jle 0x2457
movq -0x18(%rbp), %rdi
callq 0x2690
movq %rax, -0x20(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
movslq 0x5c(%rcx), %rcx
cmpq %rcx, %rax
jge 0x2626
movq -0x30(%rbp), %rax
cmpl $0x0, 0x3c(%rax)
je 0x2487
movq -0x18(%rbp), %rdi
callq 0x2980
leaq -0x48(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x20f0
imulq $0xf4240, -0x48(%rbp), %rax # imm = 0xF4240
addq -0x40(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, 0x58(%rax)
je 0x24c1
movq -0x30(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x2c40
movq %rax, -0x28(%rbp)
jmp 0x24d2
movq -0x30(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x2d40
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x24f8
movq 0xcb18(%rip), %rax      # 0xeff8
movq (%rax), %rdi
leaq 0x8c08(%rip), %rsi      # 0xb0f2
movb $0x0, %al
callq 0x2150
xorl %edi, %edi
callq 0x2200
leaq -0x48(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x20f0
imulq $0xf4240, -0x48(%rbp), %rax # imm = 0xF4240
addq -0x40(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x30(%rbp), %rax
cmpl $0x0, 0x20(%rax)
je 0x25bf
movq -0x30(%rbp), %rax
cmpl $0x0, 0x58(%rax)
je 0x2576
movq 0xcac4(%rip), %rax      # 0xeff8
movq (%rax), %rdi
movq -0x58(%rbp), %rax
subq -0x50(%rbp), %rax
movl $0xf4240, %ecx          # imm = 0xF4240
xorl %edx, %edx
divq %rcx
movq %rax, -0x68(%rbp)
movq -0x58(%rbp), %rax
subq -0x50(%rbp), %rax
movl $0xf4240, %ecx          # imm = 0xF4240
xorl %edx, %edx
divq %rcx
movq %rdx, %rcx
movq -0x68(%rbp), %rdx
leaq 0x8bab(%rip), %rsi      # 0xb118
movb $0x0, %al
callq 0x2150
jmp 0x25bd
movq 0xca7b(%rip), %rax      # 0xeff8
movq (%rax), %rdi
movq -0x58(%rbp), %rax
subq -0x50(%rbp), %rax
movl $0xf4240, %ecx          # imm = 0xF4240
xorl %edx, %edx
divq %rcx
movq %rax, -0x70(%rbp)
movq -0x58(%rbp), %rax
subq -0x50(%rbp), %rax
movl $0xf4240, %ecx          # imm = 0xF4240
xorl %edx, %edx
divq %rcx
movq %rdx, %rcx
movq -0x70(%rbp), %rdx
leaq 0x8b61(%rip), %rsi      # 0xb117
movb $0x0, %al
callq 0x2150
jmp 0x25bf
movq -0x30(%rbp), %rdi
movq -0x28(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x38(%rbp), %rcx
callq 0x3220
movq -0x28(%rbp), %rdi
callq 0x3310
movq -0x18(%rbp), %rdi
callq 0x3370
movq -0x30(%rbp), %rax
cmpl $0x1, 0x5c(%rax)
jle 0x2613
movq -0x38(%rbp), %rax
movq -0x30(%rbp), %rcx
movl 0x5c(%rcx), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
cmpq %rcx, %rax
jge 0x2613
movq -0x20(%rbp), %rdi
callq 0x2690
movq %rax, -0x18(%rbp)
jmp 0x2615
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x245f
movq -0x30(%rbp), %rax
cmpl $0x1, 0x5c(%rax)
jle 0x2639
movq -0x20(%rbp), %rdi
callq 0x3370
movq -0x30(%rbp), %rax
cmpl $0x0, 0x20(%rax)
je 0x267d
movq -0x30(%rbp), %rax
cmpl $0x0, 0x58(%rax)
je 0x2665
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0x8ae7(%rip), %rdi      # 0xb143
movb $0x0, %al
callq 0x20e0
jmp 0x267b
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
leaq 0x8ac7(%rip), %rdi      # 0xb13b
movb $0x0, %al
callq 0x20e0
jmp 0x267d
xorl %edi, %edi
callq 0x2200
nopw %cs:(%rax,%rax)