// File: /workspace/github_c_makefile_star2_O3/jsh58[P]Genrich/Genrich.c
// Function: savePileupCtrl
void savePileupCtrl(Chrom* chrom, int chromLen,
    double fragLen, uint64_t genomeLen, bool verbose) {

  // calculate background lambda value
  float lambda = calcLambda(chrom, chromLen, fragLen, genomeLen);
  if (verbose)
    fprintf(stderr, "  Background pileup value: %f\n", lambda);

  // calculate scale factor (experimental / control)
  float factor = calcFactor(chrom, chromLen, fragLen);
  if (verbose) {
    fprintf(stderr, "  Scaling factor for control pileup: %f\n", factor);
    if (factor > 5.0f)
      fprintf(stderr, "  ** Warning! Large scaling may mask true signal **\n");
  }

  // create pileup for each chrom
  for (int i = 0; i < chromLen; i++) {
    Chrom* chr = chrom + i;
    if (chr->skip || ! chr->save)
      continue;

    // if no read coverage, save constant pileup of lambda
    if (chr->diff == NULL) {
      saveLambda(chr, lambda);
      continue;
    }

    // expand pileup arrays (if necessary)
    //   (chr->ctrlLen already set in calcFactor())
    if (chr->ctrlLen > chr->ctrlMem) {
      chr->ctrl->end = (uint32_t*) memrealloc(chr->ctrl->end,
        chr->ctrlLen * sizeof(uint32_t));
      chr->ctrl->cov = (float*) memrealloc(chr->ctrl->cov,
        chr->ctrlLen * sizeof(float));
      chr->ctrlMem = chr->ctrlLen;
    }

    // initialize BED interval variables
    int bedIdx = 0;         // index into chr->bed array
    uint32_t bedPos = bedIdx < chr->bedLen ?
      chr->bed[bedIdx] : chr->len + 1;  // position of BED interval
    bool save = true;
    if (bedPos == 0) {
      // first BED interval starts at 0 (should be skipped)
      save = false;
      bedIdx++;
      bedPos = bedIdx < chr->bedLen ?
        chr->bed[bedIdx] : chr->len + 1;
    }

    // initialize pileup values
    Diff* d = chr->diff;
    int32_t cov = 0;      // current pileup value
    uint8_t frac = 0;     // current pileup value (fraction part)
    float val = factor * updateVal(d->cov[0], d->frac[0],
      &cov, &frac);
    float net = MAX(val, lambda);

    // save pileup values along the chrom
    uint32_t pos = 0;     // position in pileup arrays
    uint32_t j;
    for (j = 1; j < chr->len; j++) {

      // update pileup value
      if (d->cov[j] || d->frac[j])
        val = factor * updateVal(d->cov[j], d->frac[j],
          &cov, &frac);

      // determine if interval should be saved
      if (j == bedPos || (save && net != MAX(val, lambda))) {
        chr->ctrl->end[pos] = j;
        chr->ctrl->cov[pos] = save ? net : SKIP;
        pos++;
      }
      net = MAX(val, lambda);

      // update 'save' status (from BED intervals)
      if (j == bedPos) {
        save = ! save;
        bedIdx++;
        bedPos = bedIdx < chr->bedLen ?
          chr->bed[bedIdx] : chr->len + 1;
      }

    }

    // save final interval
    chr->ctrl->end[pos] = j;
    chr->ctrl->cov[pos] = save ? net : SKIP;

    // update array length
    if (pos >= chr->ctrlLen) {
      char msg[MAX_ALNS];
      sprintf(msg, "%s (%s)", errMsg[ERRARRC], chr->name);
      exit(error(msg, ERRISSUE));
    }
    chr->ctrlLen = pos + 1;

    // check for val error (should end at 0)
    val = updateVal(d->cov[j], d->frac[j], &cov, &frac);
    if (val) {
      char msg[MAX_ALNS];
      sprintf(msg, "Control pileup for ref %s finishes at %f (not 0.0)",
        chr->name, val);
      exit(error(msg, ERRISSUE));
    }
  }

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movl %ecx, %r14d
movl %esi, %ebp
movq %rdi, %r15
movsd %xmm0, 0x18(%rsp)
callq 0x7866
movss %xmm0, 0x10(%rsp)
testl %r14d, %r14d
jne 0x81f0
movq %r15, %rdi
movl %ebp, %esi
movsd 0x18(%rsp), %xmm0
callq 0x7c75
movss %xmm0, 0x14(%rsp)
testl %ebp, %ebp
jle 0x81de
movl %ebp, %r14d
xorl %r13d, %r13d
movq %r15, 0x30(%rsp)
movq %r14, 0x28(%rsp)
imulq $0x68, %r13, %r12
cmpb $0x0, 0xc(%r15,%r12)
jne 0x81d2
addq %r15, %r12
cmpb $0x1, 0xd(%r12)
jne 0x81d2
cmpq $0x0, 0x20(%r12)
je 0x7fb4
movl 0x40(%r12), %esi
cmpl 0x44(%r12), %esi
jbe 0x7fa2
movq 0x38(%r12), %rax
movq (%rax), %rdi
shlq $0x2, %rsi
callq 0x3925
movq 0x38(%r12), %rcx
movq %rax, (%rcx)
movq 0x8(%rcx), %rdi
movl 0x40(%r12), %esi
shlq $0x2, %rsi
callq 0x3925
movq 0x38(%r12), %rcx
movq %rax, 0x8(%rcx)
movl 0x40(%r12), %eax
movl %eax, 0x44(%r12)
movl 0x18(%r12), %eax
testl %eax, %eax
jle 0x7fc7
movq 0x10(%r12), %rcx
movl (%rcx), %ebp
jmp 0x7fce
movq %r12, %rdi
movss 0x10(%rsp), %xmm0
callq 0x78f9
jmp 0x81d2
movl 0x8(%r12), %ebp
incl %ebp
movb $0x1, %cl
xorl %r15d, %r15d
movl $0x0, %edx
testl %ebp, %ebp
jne 0x7ff9
cmpl $0x2, %eax
jl 0x7feb
movq 0x10(%r12), %rax
movl 0x4(%rax), %ebp
jmp 0x7ff2
movl 0x8(%r12), %ebp
incl %ebp
movl $0x1, %edx
xorl %ecx, %ecx
movl %edx, 0x24(%rsp)
movq %r13, 0x38(%rsp)
movl %ecx, 0x18(%rsp)
movq 0x20(%r12), %r13
movl $0x0, 0x20(%rsp)
movb $0x0, 0xf(%rsp)
movq (%r13), %rax
movq 0x8(%r13), %rcx
movswl (%rcx), %edi
movzbl (%rax), %esi
leaq 0x20(%rsp), %rdx
leaq 0xf(%rsp), %rcx
callq 0x7adf
mulss 0x14(%rsp), %xmm0
movaps %xmm0, %xmm2
maxss 0x10(%rsp), %xmm2
movl $0x1, %r14d
cmpl $0x2, 0x8(%r12)
jb 0x8151
xorl %r15d, %r15d
movl $0x1, %r14d
movl 0x18(%rsp), %edi
movq (%r13), %rcx
movq 0x8(%r13), %rax
movzwl (%rax,%r14,2), %eax
testw %ax, %ax
sete %dl
movb (%rcx,%r14), %cl
testb %cl, %cl
sete %sil
testb %sil, %dl
jne 0x80b0
movl %edi, %ebx
movswl %ax, %edi
movzbl %cl, %esi
leaq 0x20(%rsp), %rdx
leaq 0xf(%rsp), %rcx
movss %xmm2, 0x18(%rsp)
callq 0x7adf
movss 0x18(%rsp), %xmm2
movl %ebx, %edi
mulss 0x14(%rsp), %xmm0
movl %ebp, %eax
cmpq %rax, %r14
jne 0x80c7
testb $0x1, %dil
jne 0x80dd
movss 0xa08b(%rip), %xmm2     # 0x12150
jmp 0x80dd
testb $0x1, %dil
je 0x8129
movaps %xmm0, %xmm1
maxss 0x10(%rsp), %xmm1
ucomiss %xmm1, %xmm2
jne 0x80dd
jnp 0x8129
movq 0x38(%r12), %rdx
movq (%rdx), %rcx
movl %r15d, %esi
movl %r14d, (%rcx,%rsi,4)
leal 0x1(%r15), %ecx
movq 0x8(%rdx), %rdx
movss %xmm2, (%rdx,%rsi,4)
movaps %xmm0, %xmm2
maxss 0x10(%rsp), %xmm2
cmpq %rax, %r14
jne 0x813b
xorb $0x1, %dil
movl 0x24(%rsp), %edx
incl %edx
cmpl 0x18(%r12), %edx
movl %edx, 0x24(%rsp)
jge 0x8134
movq 0x10(%r12), %rax
movslq %edx, %rdx
movl (%rax,%rdx,4), %ebp
jmp 0x813b
movaps %xmm0, %xmm2
maxss 0x10(%rsp), %xmm2
jmp 0x813e
movl 0x8(%r12), %ebp
incl %ebp
movl %ecx, %r15d
incq %r14
movl 0x8(%r12), %eax
cmpq %rax, %r14
jb 0x8063
jmp 0x8155
movl 0x18(%rsp), %edi
movq 0x38(%r12), %rax
movq (%rax), %rdx
movl %r15d, %ecx
movl %r14d, (%rdx,%rcx,4)
testb $0x1, %dil
jne 0x8172
movss 0x9fde(%rip), %xmm2     # 0x12150
movq 0x8(%rax), %rax
movss %xmm2, (%rax,%rcx,4)
cmpl 0x40(%r12), %r15d
jae 0x8259
incl %r15d
movl %r15d, 0x40(%r12)
movq (%r13), %rax
movq 0x8(%r13), %rcx
movl %r14d, %edx
movswl (%rcx,%rdx,2), %edi
movzbl (%rax,%rdx), %esi
leaq 0x20(%rsp), %rdx
leaq 0xf(%rsp), %rcx
callq 0x7adf
ucomiss 0x9fb9(%rip), %xmm0     # 0x12170
jne 0x8266
jp 0x8266
movq 0x30(%rsp), %r15
movq 0x28(%rsp), %r14
movq 0x38(%rsp), %r13
incq %r13
cmpq %r14, %r13
jne 0x7f31
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x11e01(%rip), %rbx     # 0x19ff8
movq (%rbx), %rdi
xorps %xmm0, %xmm0
cvtss2sd 0x10(%rsp), %xmm0
leaq 0xb674(%rip), %rsi      # 0x1387e
movb $0x1, %al
callq 0x21d0
movq %r15, %rdi
movl %ebp, %esi
movsd 0x18(%rsp), %xmm0
callq 0x7c75
movss %xmm0, 0x14(%rsp)
movq (%rbx), %rdi
cvtss2sd %xmm0, %xmm0
leaq 0xb668(%rip), %rsi      # 0x1389d
movb $0x1, %al
callq 0x21d0
movss 0x14(%rsp), %xmm0
ucomiss 0x9f23(%rip), %xmm0     # 0x1216c
jbe 0x7f19
callq 0x2cae
jmp 0x7f19
leaq 0x40(%rsp), %rdi
movq %r12, %rsi
callq 0x2cca
leaq 0x40(%rsp), %rdi
movq %r12, %rsi
callq 0x2cf9