// File: /workspace/github_c_makefile_star2_O1/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, 0x20(%rsp)
callq 0x784a
movss %xmm0, 0x10(%rsp)
testl %r14d, %r14d
jne 0x81a2
movq %r15, %rdi
movl %ebp, %esi
movsd 0x20(%rsp), %xmm0
callq 0x7c5a
movss %xmm0, 0x14(%rsp)
testb %r14b, %r14b
jne 0x81b2
testl %ebp, %ebp
jle 0x8190
movl %ebp, %ebx
xorl %r14d, %r14d
movq %rbx, 0x28(%rsp)
movq %r15, 0x30(%rsp)
imulq $0x68, %r14, %r12
cmpb $0x0, 0xc(%r15,%r12)
jne 0x8184
addq %r15, %r12
cmpb $0x1, 0xd(%r12)
jne 0x8184
cmpq $0x0, 0x20(%r12)
je 0x7fa3
movl 0x40(%r12), %esi
cmpl 0x44(%r12), %esi
jbe 0x7f8c
movq 0x38(%r12), %rax
movq (%rax), %rdi
shlq $0x2, %rsi
callq 0x3915
movq 0x38(%r12), %rcx
movq %rax, (%rcx)
movq 0x8(%rcx), %rdi
movl 0x40(%r12), %esi
shlq $0x2, %rsi
callq 0x3915
movq 0x38(%r12), %rcx
movq %rax, 0x8(%rcx)
movl 0x40(%r12), %eax
movl %eax, 0x44(%r12)
movl 0x18(%r12), %eax
testl %eax, %eax
movq %r14, 0x38(%rsp)
jle 0x7fb6
movq 0x10(%r12), %rcx
movl (%rcx), %ebx
jmp 0x7fbd
movq %r12, %rdi
movss 0x10(%rsp), %xmm0
callq 0x78dd
jmp 0x8184
movl 0x8(%r12), %ebx
incl %ebx
movb $0x1, %r14b
xorl %r13d, %r13d
movl $0x0, %ecx
testl %ebx, %ebx
jne 0x7fea
cmpl $0x2, %eax
jl 0x7fdb
movq 0x10(%r12), %rax
movl 0x4(%rax), %ebx
jmp 0x7fe2
movl 0x8(%r12), %ebx
incl %ebx
movl $0x1, %ecx
xorl %r14d, %r14d
movl %ecx, 0x1c(%rsp)
movq 0x20(%r12), %r15
movl $0x0, 0x18(%rsp)
movb $0x0, 0xf(%rsp)
movq (%r15), %rax
movq 0x8(%r15), %rcx
movswl (%rcx), %edi
movzbl (%rax), %esi
leaq 0x18(%rsp), %rdx
leaq 0xf(%rsp), %rcx
callq 0x7aca
mulss 0x14(%rsp), %xmm0
movaps %xmm0, %xmm2
maxss 0x10(%rsp), %xmm2
movl $0x1, %ebp
cmpl $0x2, 0x8(%r12)
jb 0x8112
xorl %r13d, %r13d
movl $0x1, %ebp
movq 0x8(%r15), %rax
movzwl (%rax,%rbp,2), %eax
testw %ax, %ax
jne 0x805a
movq (%r15), %rcx
cmpb $0x0, (%rcx,%rbp)
je 0x8085
movq (%r15), %rcx
movzbl (%rcx,%rbp), %esi
movswl %ax, %edi
leaq 0x18(%rsp), %rdx
leaq 0xf(%rsp), %rcx
movss %xmm2, 0x20(%rsp)
callq 0x7aca
movss 0x20(%rsp), %xmm2
mulss 0x14(%rsp), %xmm0
movl %ebx, %eax
cmpq %rax, %rbp
je 0x80a2
testb $0x1, %r14b
je 0x80ca
movaps %xmm0, %xmm1
maxss 0x10(%rsp), %xmm1
ucomiss %xmm1, %xmm2
jne 0x80a2
jnp 0x80ca
movq 0x38(%r12), %rcx
movq (%rcx), %rsi
movl %r13d, %edx
movl %ebp, (%rsi,%rdx,4)
testb $0x1, %r14b
jne 0x80be
movss 0xa09a(%rip), %xmm2     # 0x12158
movq 0x8(%rcx), %rcx
movss %xmm2, (%rcx,%rdx,4)
incl %r13d
cmpq %rax, %rbp
jne 0x80f8
xorb $0x1, %r14b
movl 0x1c(%rsp), %ecx
incl %ecx
cmpl 0x18(%r12), %ecx
movl %ecx, 0x1c(%rsp)
jge 0x80f1
movq 0x10(%r12), %rax
movslq %ecx, %rcx
movl (%rax,%rcx,4), %ebx
jmp 0x80f8
movl 0x8(%r12), %ebx
incl %ebx
movaps %xmm0, %xmm2
maxss 0x10(%rsp), %xmm2
incq %rbp
movl 0x8(%r12), %eax
cmpq %rax, %rbp
jb 0x8044
movq 0x38(%r12), %rax
movq (%rax), %rdx
movl %r13d, %ecx
movl %ebp, (%rdx,%rcx,4)
testb $0x1, %r14b
jne 0x812e
movss 0xa02a(%rip), %xmm2     # 0x12158
movq 0x8(%rax), %rax
movss %xmm2, (%rax,%rcx,4)
cmpl 0x40(%r12), %r13d
jae 0x81c2
incl %r13d
movl %r13d, 0x40(%r12)
movq (%r15), %rax
movq 0x8(%r15), %rcx
movl %ebp, %edx
movswl (%rcx,%rdx,2), %edi
movzbl (%rax,%rdx), %esi
leaq 0x18(%rsp), %rdx
leaq 0xf(%rsp), %rcx
callq 0x7aca
ucomiss 0xa003(%rip), %xmm0     # 0x12174
jne 0x81cf
jp 0x81cf
movq 0x30(%rsp), %r15
movq 0x28(%rsp), %rbx
movq 0x38(%rsp), %r14
incq %r14
cmpq %rbx, %r14
jne 0x7f1b
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movss 0x10(%rsp), %xmm0
callq 0x2c96
jmp 0x7ee5
movss 0x14(%rsp), %xmm0
callq 0x2cb2
jmp 0x7f04
leaq 0x40(%rsp), %rdi
movq %r12, %rsi
callq 0x2d08
leaq 0x40(%rsp), %rdi
movq %r12, %rsi
callq 0x2d37