// File: /workspace/github_c_makefile_star2_O1/sc932[P]ALE/src/ALEhelpers.c
// Function: computeLibraryParameters
libraryParametersT *computeLibraryParameters(samfile_t *ins, double outlierFraction, int qOff) {

  int i,j;
  long *mapLens[MATE_ORIENTATION_MAX];

  // allocate memory
  for(i=0; i < MATE_ORIENTATION_MAX; i++)
    mapLens[i] = malloc(sizeof(long)*mapLens_MAX);
  libraryParametersT *libParams = malloc(sizeof(libraryParametersT));

  // initialize
  for(j=0; j < MATE_ORIENTATION_MAX; j++) {
    for(i = 0; i < mapLens_MAX; i++)
      mapLens[j][i] = 0;
    libParams->mateParameters[j].insertLength = 0.0;
    libParams->mateParameters[j].insertStd = 0.0;
    libParams->mateParameters[j].zNormalizationInsert = 1.0;
    libParams->mateParameters[j].count = 0;
    libParams->mateParameters[j].mapped = 0;
    libParams->mateParameters[j].placed = 0;
    libParams->mateParameters[j].isValid = 0;
  }
  // set SINGLE_READ insert parameters
  libParams->mateParameters[SINGLE_READ].insertStd = 1.0;
  libParams->mateParameters[SINGLE_READ].zNormalizationInsert = zNormalizationInsertStd(1.0);

  libParams->qOff = qOff;
  libParams->avgReadSize = 0;
  libParams->numReads = 0;
  libParams->isSortedByName = -1; // undefined
  libParams->primaryOrientation = SINGLE_READ;  // can be only SINGLE_READ or the most abundant of the MAPPED_PAIRED_ORIENTATION


  bam1_t *thisRead = bam_init1();
  long readCount = 0;
  long unmappedReads = 0;
  long chimericReads = 0;
  long improperReads = 0;
  long mappedPairedReads = 0;
  long newNames = 0;
  long newPairedNames = 0;
  long pairedReads = 0;
  char *lastName = strdup("");

  while(1){
    enum MATE_ORIENTATION orientation = readNextBAM(ins, thisRead);

    if (orientation == NO_READS){
      break;
    }

    libraryMateParametersT *mateParams = &libParams->mateParameters[orientation];

    int mapLen = -1;
    switch(orientation) {
      case(VALID_FR):
      case(VALID_RF):
      case(VALID_FF):
      case(NOT_PROPER_FR):
      case(NOT_PROPER_RF):
      case(NOT_PROPER_FF):
        mapLen = getFragmentMapLenBAM(thisRead);
        mappedPairedReads++;
        break;

      case(SINGLE_READ):
      case(UNMAPPED_SINGLE):
        break;

      case(SINGLE_UNMAPPED_MATE):
        break;

      case(CHIMER):
        chimericReads++;
        break;

      case(UNMAPPED_PAIR):
      case(UNMAPPED_MATE):
        break;

      default:
        // should never get here
        printf("Improper read with invalid orientation/pairing: %s\n", lastName);
        improperReads++;
    }

    readCount++;
    mateParams->count++;
    libParams->avgReadSize += thisRead->core.l_qseq;
    libParams->numReads++;
    if (libParams->qOff < 0) {
      libParams->qOff = guessQualityOffset(thisRead);
    }

    if ( (thisRead->core.flag & BAM_FUNMAP) == BAM_FUNMAP ) {
        unmappedReads++;
    } else {
    	mateParams->mapped++;
    }

    if ( (thisRead->core.flag & BAM_FPAIRED) == BAM_FPAIRED ) {
    	pairedReads++;
    }
    if (strcmp(lastName, bam1_qname(thisRead)) != 0){
        newNames++;
        if ( (thisRead->core.flag & BAM_FPAIRED) == BAM_FPAIRED ) {
        	newPairedNames++;
        }
    }
    free(lastName);
    lastName = strdup(bam1_qname(thisRead));

    if (mapLen > 0) {
      mateParams->insertLength += mapLen;
      if (mapLen < mapLens_MAX){
        ++mapLens[orientation][mapLen];
      }
    }

    if (readCount%1000000 == 0){
      printf("Read %ld reads...\n", readCount);
    }
  }
  bam_destroy1(thisRead);
  free(lastName);

  if (pairedReads > 0 && newNames <= readCount/2 && newPairedNames == pairedReads / 2) {
    libParams->isSortedByName = 1;
    printf("Setting library to be sorted by name (%ld new sequential names vs %ld reads)\n", newNames, readCount);
  } else {
    libParams->isSortedByName = 0;
  }

  // zero out top and bottom outliers
  long totalValidMateReads = 0;
  long totalValidSingleReads = 0;
  double maximumFraction = 0.0;
  double pairedReadsFraction = (double) mappedPairedReads / (double) libParams->numReads;
  for(j = 0; j < MATE_ORIENTATION_MAX; j++) {
    libraryMateParametersT *mateParams = &libParams->mateParameters[j];
    //printf("Evaluating %s orientation with %ld reads\n", MATE_ORIENTATION_LABELS[j], mateParams->count);
    long observed = 0;
    long purged = 0;
    long lengthTotal = 0;
    for(i = 0; i < mapLens_MAX; i++) {
      if (observed > (1.0-outlierFraction) * mateParams->count) {
        purged += mapLens[j][i];
        mapLens[j][i] = 0;
      } else {
        observed += mapLens[j][i];
        lengthTotal += i*mapLens[j][i];
      }
      if (observed < outlierFraction * mateParams->count) {
        purged += mapLens[j][i];
        mapLens[j][i] = 0;
      }
    }
    mateParams->libraryFraction = (double) mateParams->count / (double) libParams->numReads;
    if (mateParams->libraryFraction > maximumFraction && j <= MAPPED_PAIRED_ORIENTATION) {
        maximumFraction = mateParams->libraryFraction;
        libParams->primaryOrientation = j;
    }

    if (mateParams->count > 0 && (j == VALID_FR || j == VALID_RF || j == VALID_FF || j == NOT_PROPER_FR || j == NOT_PROPER_RF || j == NOT_PROPER_FF )) {

      // TODO better test for significance and normal distribution for a valid orientation
      if (mateParams->libraryFraction > SIGNIFICANT_LIBRARY_FRACTION * pairedReadsFraction ) {
        mateParams->isValid = 1;
      } else {
        improperReads += mateParams->count;
        mateParams->isValid = 0;
      }

    } else if (mateParams->count > 0 && (j == SINGLE_READ || j == SINGLE_UNMAPPED_MATE)) {
        totalValidSingleReads += mateParams->count;
        mateParams->isValid = 1;
    } else {
        improperReads += mateParams->count;
        mateParams->isValid = 0;
    }

    if (mateParams->isValid == 1) {
      /*printf("Read %ld %s oriented sequences and purged %ld %0.1lf%% & %0.1lf%% outliers.  This %s a valid orientation (%01lf%%)\n",
          mateParams->count,
          MATE_ORIENTATION_LABELS[j],
          purged,
          (outlierFraction*100.0),
          ((1.0-outlierFraction)*100.0),
          mateParams->isValid ? "is" : "is NOT",
          mateParams->libraryFraction*100.0);*/
    }

    long modifiedReadCount = mateParams->count - purged;

    if (mateParams->isValid && j <= MAPPED_PAIRED_ORIENTATION) {
      mateParams->insertLength = (double)lengthTotal/(double)modifiedReadCount;
      for(i = 0; i < mapLens_MAX; i++){
        if(mapLens[j][i] > 0){
          double tmp = mapLens[j][i]*((double)i - mateParams->insertLength)*((double)i - mateParams->insertLength);
          mateParams->insertStd += tmp;
          //printf("i : %s mapLens[i] :: %i : %ld\n", MATE_ORIENTATION_LABELS[j], i, mapLens[j][i]);
        }
      }
      mateParams->insertStd = sqrt(mateParams->insertStd/(double)(modifiedReadCount-1));
      mateParams->zNormalizationInsert = zNormalizationInsertStd(mateParams->insertStd);
      printf("Found %s sample avg insert length to be %lf from %ld mapped reads\n", MATE_ORIENTATION_LABELS[j], mateParams->insertLength, modifiedReadCount);
      printf("Found %s sample insert length std to be %lf\n", MATE_ORIENTATION_LABELS[j], mateParams->insertStd);
      if (mateParams->insertStd > MAXIMUM_STD_DEV_FRACTION * mateParams->insertLength) {
    	  mateParams->isValid = 0;
    	  improperReads += mateParams->count;
    	  printf("stddev is too large (> %lf * insertLength).  This orientation is invalid\n", MAXIMUM_STD_DEV_FRACTION );
      } else {
          totalValidMateReads += mateParams->count;
      }
    }
  }
  printf("There were %ld total reads, %ld paired (%ld properly mated), %ld proper singles, %ld improper reads (%ld chimeric). (%ld reads were unmapped)\n", readCount, pairedReads, totalValidMateReads, totalValidSingleReads, improperReads, chimericReads, unmappedReads);

  libParams->avgReadSize = libParams->avgReadSize / libParams->numReads;

  libParams->totalValidMateFraction = (double) (totalValidMateReads) / (double) libParams->numReads;
  libParams->totalValidSingleFraction = (double) totalValidSingleReads / (double) libParams->numReads;
  libParams->totalChimerMateFraction = (double) (improperReads) / (double) libParams->numReads;
  libParams->totalUnmappedFraction = (double) unmappedReads / (double) libParams->numReads;

  /*printf("ValidMates %0.3lf%%, Single(+half-mapped mate pairs) %0.3lf%%, Improper/ChimerMates %0.3lf%% (Unmapped %0.3lf%%)\n",
          libParams->totalValidMateFraction*100,
          libParams->totalValidSingleFraction*100,
          libParams->totalChimerMateFraction*100,
          libParams->totalUnmappedFraction*100);*/

  // release memory
  for(i=0; i < MATE_ORIENTATION_MAX; i++)
    free(mapLens[i]);

  return libParams;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x108, %rsp            # imm = 0x108
movl %esi, %ebp
movsd %xmm0, 0x20(%rsp)
movq %rdi, 0x48(%rsp)
xorl %ebx, %ebx
movl $0xc3500, %edi          # imm = 0xC3500
callq 0x3420
movq %rax, 0x90(%rsp,%rbx,8)
incq %rbx
cmpq $0xe, %rbx
jne 0xc744
movl $0x3c0, %edi            # imm = 0x3C0
callq 0x3420
movq %rax, %r15
xorl %ebx, %ebx
movabsq $0x3ff0000000000000, %r14 # imm = 0x3FF0000000000000
movq 0x90(%rsp,%rbx), %rdi
movl $0xc3500, %edx          # imm = 0xC3500
xorl %esi, %esi
callq 0x3260
xorpd %xmm0, %xmm0
movupd %xmm0, (%r15,%rbx,8)
movq %r14, 0x10(%r15,%rbx,8)
movupd %xmm0, 0x20(%r15,%rbx,8)
movupd %xmm0, 0x2c(%r15,%rbx,8)
addq $0x8, %rbx
cmpq $0x70, %rbx
jne 0xc778
movq %r14, 0x2c8(%r15)
movabsq $0x3fd20dd7506ee8c4, %rax # imm = 0x3FD20DD7506EE8C4
movq %rax, 0x2d0(%r15)
movl %ebp, 0x3b0(%r15)
movupd %xmm0, 0x380(%r15)
movabsq $0xbffffffff, %rax      # imm = 0xBFFFFFFFF
movq %rax, 0x3b4(%r15)
movl $0x1, %edi
movl $0x38, %esi
callq 0x3310
movq %rax, %rbx
leaq 0x17f7f(%rip), %rdi     # 0x24784
callq 0x3630
movq %rbx, %rsi
movq %rax, 0x10(%rsp)
movq $0x0, 0x50(%rsp)
xorl %ebp, %ebp
xorl %r14d, %r14d
movq $0x0, 0x28(%rsp)
xorl %ebx, %ebx
movq $0x0, 0x70(%rsp)
movq $0x0, 0x78(%rsp)
xorl %r13d, %r13d
movq %r15, 0x40(%rsp)
movq %rsi, 0x8(%rsp)
movq 0x48(%rsp), %rdi
callq 0xbc59
movl %eax, %r12d
cmpl $0xd, %eax
je 0xca02
movq %r13, 0x68(%rsp)
movl $0xffffffff, %r13d      # imm = 0xFFFFFFFF
movq 0x8(%rsp), %rdi
movq %rbp, 0x60(%rsp)
jae 0xca13
movl $0x3f, %eax
btl %r12d, %eax
jb 0xc8a2
movl $0x1b40, %eax           # imm = 0x1B40
btl %r12d, %eax
jb 0xc8b4
cmpl $0x7, %r12d
jne 0xca13
incq 0x70(%rsp)
jmp 0xc8b4
callq 0xba81
movq 0x8(%rsp), %rdi
movl %eax, %r13d
incq 0x50(%rsp)
movq %r14, 0x80(%rsp)
movl %r12d, %ebp
movq %rbp, 0x58(%rsp)
shlq $0x6, %rbp
addq %r15, %rbp
incq 0x20(%rbp)
movslq 0x10(%rdi), %rax
addq %rax, 0x380(%r15)
incq 0x388(%r15)
cmpl $0x0, 0x3b0(%r15)
jns 0xc8fc
callq 0x89e1
movq 0x8(%rsp), %rdi
movl %eax, 0x3b0(%r15)
movq 0x8(%rdi), %r14
btq $0x22, %r14
movq %rbx, 0x18(%rsp)
movl %r13d, 0x38(%rsp)
jb 0xc917
incq 0x28(%rbp)
jmp 0xc91c
incq 0x78(%rsp)
btq $0x20, %r14
adcq $0x0, 0x28(%rsp)
movq %rdi, %r13
movq 0x30(%rdi), %rsi
movq 0x10(%rsp), %r15
movq %r15, %rdi
callq 0x3330
xorl %ebx, %ebx
testl %eax, %eax
setne 0x30(%rsp)
movq %r15, %rdi
callq 0x3070
movq 0x30(%r13), %rdi
callq 0x3630
movq %rax, 0x10(%rsp)
movl 0x38(%rsp), %ecx
testl %ecx, %ecx
jle 0xc98b
cvtsi2sd %ecx, %xmm0
addsd (%rbp), %xmm0
movsd %xmm0, (%rbp)
cmpl $0x1869f, %ecx          # imm = 0x1869F
jg 0xc98b
movq 0x58(%rsp), %rax
movq 0x90(%rsp,%rax,8), %rax
movl %ecx, %ecx
incq (%rax,%rcx,8)
movq 0x68(%rsp), %r13
incq %r13
shrq $0x20, %r14
movb 0x30(%rsp), %al
movb %al, %bl
movq 0x60(%rsp), %rbp
addq %rbx, %rbp
andl %ebx, %r14d
movq 0x80(%rsp), %rax
addq %r14, %rax
movq %rax, %r14
movq %r13, %rax
movabsq $0x790fb65668c26139, %rcx # imm = 0x790FB65668C26139
imulq %rcx, %rax
movabsq $0x218def416bd80, %rcx  # imm = 0x218DEF416BD80
addq %rcx, %rax
rorq $0x6, %rax
movabsq $0x10c6f7a0b5ec, %rcx   # imm = 0x10C6F7A0B5EC
cmpq %rcx, %rax
ja 0xc9f8
leaq 0x161c4(%rip), %rdi     # 0x22bb2
movq %r13, %rsi
xorl %eax, %eax
callq 0x3210
movq 0x40(%rsp), %r15
movq 0x18(%rsp), %rbx
movq 0x8(%rsp), %rsi
cmpl $0xd, %r12d
jne 0xc84a
jmp 0xca33
leaq 0x17731(%rip), %rdi     # 0x2414b
movq 0x10(%rsp), %rsi
xorl %eax, %eax
callq 0x3210
movq 0x8(%rsp), %rdi
incq %rbx
jmp 0xc8b4
testq %rsi, %rsi
je 0xca4c
movq 0x30(%rsi), %rdi
movq %rsi, %r12
callq 0x3070
movq %r12, %rdi
callq 0x3070
movq 0x10(%rsp), %rdi
callq 0x3070
cmpq $0x0, 0x28(%rsp)
movq %r13, 0x68(%rsp)
jle 0xcaa3
movq %r13, %rax
shrq $0x3f, %rax
addq %r13, %rax
sarq %rax
cmpq %rax, %rbp
jg 0xcaa3
movq 0x28(%rsp), %rax
shrq %rax
cmpq %rax, %r14
jne 0xcaa3
movl $0x1, 0x3b4(%r15)
leaq 0x176eb(%rip), %rdi     # 0x2417f
movq %rbp, %rsi
movq %r13, %rdx
xorl %eax, %eax
callq 0x3210
jmp 0xcaae
movl $0x0, 0x3b4(%r15)
movsd 0x20(%rsp), %xmm3
movq 0x50(%rsp), %rax
cvtsi2sd %rax, %xmm1
movq 0x388(%r15), %rax
movq %rax, 0x58(%rsp)
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movsd %xmm0, 0x48(%rsp)
divsd %xmm0, %xmm1
movsd 0x10f54(%rip), %xmm4    # 0x1da38
mulsd 0x1667c(%rip), %xmm1    # 0x23168
movsd %xmm1, 0x60(%rsp)
subsd %xmm3, %xmm4
xorl %r12d, %r12d
xorpd %xmm5, %xmm5
movq $0x0, 0x30(%rsp)
movq $0x0, 0x38(%rsp)
movapd %xmm4, 0x80(%rsp)
movq %r12, %rax
shlq $0x6, %rax
xorps %xmm0, %xmm0
cvtsi2sdq 0x20(%r15,%rax), %xmm0
leaq (%r15,%rax), %r13
movapd %xmm4, %xmm1
mulsd %xmm0, %xmm1
mulsd %xmm3, %xmm0
xorl %edx, %edx
xorl %eax, %eax
xorl %ecx, %ecx
xorl %esi, %esi
xorps %xmm2, %xmm2
cvtsi2sd %rsi, %xmm2
ucomisd %xmm1, %xmm2
jbe 0xcb65
movq 0x90(%rsp,%r12,8), %rdi
addq (%rdi,%rdx,8), %rcx
movq $0x0, (%rdi,%rdx,8)
jmp 0xcb7b
movq 0x90(%rsp,%r12,8), %rdi
movq (%rdi,%rdx,8), %rdi
addq %rdi, %rsi
imulq %rdx, %rdi
addq %rdi, %rax
xorps %xmm2, %xmm2
cvtsi2sd %rsi, %xmm2
ucomisd %xmm2, %xmm0
jbe 0xcb9d
movq 0x90(%rsp,%r12,8), %rdi
addq (%rdi,%rdx,8), %rcx
movq $0x0, (%rdi,%rdx,8)
incq %rdx
cmpq $0x186a0, %rdx          # imm = 0x186A0
jne 0xcb41
movq 0x20(%r13), %rbp
xorps %xmm0, %xmm0
cvtsi2sd %rbp, %xmm0
divsd 0x48(%rsp), %xmm0
movsd %xmm0, 0x18(%r13)
cmpq $0x5, %r12
ja 0xcbd8
ucomisd %xmm5, %xmm0
jbe 0xcbd8
movl %r12d, 0x3b8(%r15)
movapd %xmm0, %xmm5
cmpq $0x6, %r12
setae %dl
testq %rbp, %rbp
setle %sil
orb %dl, %sil
jne 0xcbf5
ucomisd 0x60(%rsp), %xmm0
ja 0xcc0b
jmp 0xcc14
testq %rbp, %rbp
jle 0xcc14
cmpl $0xb, %r12d
je 0xcc06
cmpl $0x8, %r12d
jne 0xcc14
addq %rbp, 0x30(%rsp)
movl $0x1, %esi
movb $0x1, %dl
jmp 0xcc1b
addq %rbp, %rbx
xorl %edx, %edx
xorl %esi, %esi
cmpq $0x6, %r12
setae %dil
movl %esi, 0x38(%r13)
xorb $0x1, %dl
orb %dil, %dl
jne 0xcda7
movq %rbp, %r14
subq %rcx, %r14
xorps %xmm2, %xmm2
cvtsi2sd %rax, %xmm2
xorps %xmm0, %xmm0
cvtsi2sd %r14, %xmm0
divsd %xmm0, %xmm2
movsd %xmm2, (%r13)
movq 0x90(%rsp,%r12,8), %rax
xorl %ecx, %ecx
movq (%rax,%rcx,8), %rdx
testq %rdx, %rdx
jle 0xcc8d
xorps %xmm0, %xmm0
cvtsi2sd %rdx, %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %ecx, %xmm1
subsd %xmm2, %xmm1
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
addsd 0x8(%r13), %xmm0
movsd %xmm0, 0x8(%r13)
incq %rcx
cmpq $0x186a0, %rcx          # imm = 0x186A0
jne 0xcc5d
movsd %xmm2, 0x8(%rsp)
leaq -0x1(%r14), %rax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
movsd 0x8(%r13), %xmm0
divsd %xmm1, %xmm0
ucomisd 0x10db3(%rip), %xmm0    # 0x1da70
movsd %xmm5, 0x18(%rsp)
jb 0xcccb
sqrtsd %xmm0, %xmm0
jmp 0xccd0
callq 0x3600
movsd %xmm0, 0x8(%r13)
movapd %xmm0, %xmm3
movsd %xmm0, 0x10(%rsp)
mulsd 0x16478(%rip), %xmm0    # 0x23160
movsd 0x10d48(%rip), %xmm2    # 0x1da38
movapd %xmm2, %xmm1
divsd %xmm0, %xmm1
xorpd %xmm0, %xmm0
cmpltsd %xmm3, %xmm0
andpd %xmm0, %xmm1
andnpd %xmm2, %xmm0
orpd %xmm1, %xmm0
movlpd %xmm0, 0x10(%r13)
leaq 0x1f026(%rip), %rax     # 0x2bd40
movq (%rax,%r12,8), %r15
leaq 0x174a8(%rip), %rdi     # 0x241cd
movq %r15, %rsi
movsd 0x8(%rsp), %xmm0
movq %r14, %rdx
movb $0x1, %al
callq 0x3210
leaq 0x174d1(%rip), %rdi     # 0x24210
movq %r15, %rsi
movsd 0x10(%rsp), %xmm0
movb $0x1, %al
callq 0x3210
movsd 0x16419(%rip), %xmm0    # 0x23170
movsd 0x8(%rsp), %xmm2
mulsd %xmm0, %xmm2
movsd 0x10(%rsp), %xmm1
ucomisd %xmm2, %xmm1
jbe 0xcd88
movl $0x0, 0x38(%r13)
addq %rbp, %rbx
leaq 0x174be(%rip), %rdi     # 0x2423d
movb $0x1, %al
callq 0x3210
jmp 0xcd8d
addq %rbp, 0x38(%rsp)
movq 0x40(%rsp), %r15
movsd 0x20(%rsp), %xmm3
movapd 0x80(%rsp), %xmm4
movsd 0x18(%rsp), %xmm5
incq %r12
cmpq $0xe, %r12
jne 0xcb18
leaq 0x174cc(%rip), %rdi     # 0x24287
xorl %r14d, %r14d
movq 0x68(%rsp), %rsi
movq 0x28(%rsp), %rdx
movq 0x38(%rsp), %rbp
movq %rbp, %rcx
movq 0x30(%rsp), %r13
movq %r13, %r8
movq %rbx, %r9
xorl %eax, %eax
movq 0x78(%rsp), %r10
movq %rbx, %r12
movq %r10, %rbx
pushq %r10
pushq 0x78(%rsp)
callq 0x3210
addq $0x10, %rsp
movq 0x380(%r15), %rax
cqto
idivq 0x58(%rsp)
movq %rax, 0x380(%r15)
xorps %xmm0, %xmm0
cvtsi2sd %rbp, %xmm0
movsd 0x48(%rsp), %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, 0x398(%r15)
xorps %xmm0, %xmm0
cvtsi2sd %r13, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x390(%r15)
xorps %xmm0, %xmm0
cvtsi2sd %r12, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x3a0(%r15)
xorps %xmm0, %xmm0
cvtsi2sd %rbx, %xmm0
divsd %xmm1, %xmm0
movsd %xmm0, 0x3a8(%r15)
movq 0x90(%rsp,%r14,8), %rdi
callq 0x3070
incq %r14
cmpq $0xe, %r14
jne 0xce66
movq %r15, %rax
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq