// File: /workspace/github_c_makefile_star2_O2/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, %ebp
movl %esi, %r14d
movq %rdi, %r12
movsd %xmm0, 0x18(%rsp)
callq 0x63a7
movss %xmm0, 0x8(%rsp)
testl %ebp, %ebp
jne 0x6cb7
movq %r12, %rdi
movl %r14d, %esi
movsd 0x18(%rsp), %xmm0
callq 0x6756
movss %xmm0, 0xc(%rsp)
testb %bpl, %bpl
jne 0x6cda
xorl %ebx, %ebx
testl %r14d, %r14d
cmovlel %ebx, %r14d
movss 0x8(%rsp), %xmm0
movq %r14, 0x28(%rsp)
movq %r12, 0x20(%rsp)
cmpq %r14, %rbx
je 0x6ca5
imulq $0x68, %rbx, %r13
cmpb $0x0, 0xc(%r12,%r13)
jne 0x6c9d
addq %r12, %r13
cmpb $0x1, 0xd(%r13)
jne 0x6c9d
cmpq $0x0, 0x20(%r13)
je 0x6a8d
movl 0x40(%r13), %esi
cmpl 0x44(%r13), %esi
jbe 0x6a77
movq 0x38(%r13), %rax
movq (%rax), %rdi
shlq $0x2, %rsi
callq 0x2776
movq 0x38(%r13), %rcx
movq %rax, (%rcx)
movq 0x8(%rcx), %rdi
movl 0x40(%r13), %esi
shlq $0x2, %rsi
callq 0x2776
movq 0x38(%r13), %rcx
movq %rax, 0x8(%rcx)
movl 0x40(%r13), %eax
movl %eax, 0x44(%r13)
movl 0x18(%r13), %eax
testl %eax, %eax
movq %rbx, 0x30(%rsp)
jle 0x6aa0
movq 0x10(%r13), %rcx
movl (%rcx), %r15d
jmp 0x6aa7
movq %r13, %rdi
callq 0x6444
movss 0x8(%rsp), %xmm0
jmp 0x6c9d
movl 0x8(%r13), %r15d
incl %r15d
movb $0x1, %dl
xorl %ebx, %ebx
movl $0x0, %ecx
testl %r15d, %r15d
jne 0x6ad0
cmpl $0x2, %eax
jl 0x6ac4
movq 0x10(%r13), %rax
movl 0x4(%rax), %r15d
jmp 0x6acb
movl 0x8(%r13), %r15d
incl %r15d
xorl %edx, %edx
pushq $0x1
popq %rcx
movl %ecx, 0x14(%rsp)
movq 0x20(%r13), %r12
andl $0x0, 0x10(%rsp)
movb $0x0, 0x7(%rsp)
movq (%r12), %rax
movq 0x8(%r12), %rcx
movl %edx, %ebp
movswl (%rcx), %edi
movzbl (%rax), %esi
leaq 0x10(%rsp), %rdx
leaq 0x7(%rsp), %rcx
callq 0x6647
movl %ebp, %edi
mulss 0xc(%rsp), %xmm0
movaps %xmm0, %xmm3
movss 0x8(%rsp), %xmm2
maxss %xmm2, %xmm3
pushq $0x1
popq %rbp
movq %r13, 0x38(%rsp)
movl 0x8(%r13), %eax
movl %ebx, %r14d
cmpq %rax, %rbp
jae 0x6c22
movq (%r12), %rcx
movq 0x8(%r12), %rax
movzwl (%rax,%rbp,2), %eax
testw %ax, %ax
sete %dl
movb (%rcx,%rbp), %cl
testb %cl, %cl
sete %sil
testb %sil, %dl
jne 0x6b9a
movl %ebx, %r13d
movq %r12, %rbx
movl %r15d, %r12d
movl %edi, %r15d
movswl %ax, %edi
movzbl %cl, %esi
leaq 0x10(%rsp), %rdx
leaq 0x7(%rsp), %rcx
movss %xmm3, 0x18(%rsp)
callq 0x6647
movss 0x18(%rsp), %xmm3
movl %r15d, %edi
movl %r12d, %r15d
movq %rbx, %r12
movl %r13d, %ebx
movq 0x38(%rsp), %r13
movss 0x8(%rsp), %xmm2
mulss 0xc(%rsp), %xmm0
movl %r15d, %eax
cmpq %rax, %rbp
jne 0x6bb2
testb $0x1, %dil
jne 0x6bc6
movss 0x95b8(%rip), %xmm3     # 0x10168
jmp 0x6bc6
testb $0x1, %dil
je 0x6c0a
movaps %xmm0, %xmm1
maxss %xmm2, %xmm1
ucomiss %xmm1, %xmm3
jne 0x6bc6
jnp 0x6c0a
movq 0x38(%r13), %rcx
movq (%rcx), %rdx
movl %ebp, (%rdx,%r14,4)
incl %ebx
movq 0x8(%rcx), %rcx
movss %xmm3, (%rcx,%r14,4)
movaps %xmm0, %xmm3
maxss %xmm2, %xmm3
cmpq %rax, %rbp
jne 0x6c1a
xorb $0x1, %dil
movl 0x14(%rsp), %ecx
incl %ecx
cmpl 0x18(%r13), %ecx
movl %ecx, 0x14(%rsp)
jge 0x6c13
movq 0x10(%r13), %rax
movslq %ecx, %rcx
movl (%rax,%rcx,4), %r15d
jmp 0x6c1a
movaps %xmm0, %xmm3
maxss %xmm2, %xmm3
jmp 0x6c1a
movl 0x8(%r13), %r15d
incl %r15d
incq %rbp
jmp 0x6b1f
movq 0x38(%r13), %rax
movq (%rax), %rcx
movl %ebp, (%rcx,%r14,4)
testb $0x1, %dil
jne 0x6c3b
movss 0x952d(%rip), %xmm3     # 0x10168
movq 0x8(%rax), %rax
movss %xmm3, (%rax,%r14,4)
cmpl 0x40(%r13), %ebx
jae 0x6d25
incl %ebx
movl %ebx, 0x40(%r13)
movq (%r12), %rax
movq 0x8(%r12), %rcx
movswl (%rcx,%rbp,2), %edi
movzbl (%rax,%rbp), %esi
leaq 0x10(%rsp), %rdx
leaq 0x7(%rsp), %rcx
callq 0x6647
ucomiss 0x950c(%rip), %xmm0     # 0x10188
jne 0x6d48
jp 0x6d48
movq 0x28(%rsp), %r14
movq 0x20(%rsp), %r12
movss 0x8(%rsp), %xmm0
movq 0x30(%rsp), %rbx
incq %rbx
jmp 0x6a07
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x1033a(%rip), %rax     # 0x16ff8
movq (%rax), %rdi
cvtss2sd 0x8(%rsp), %xmm0
leaq 0xab00(%rip), %rsi      # 0x117ce
movb $0x1, %al
callq 0x21c0
jmp 0x69ce
movq 0x10317(%rip), %rbx     # 0x16ff8
movq (%rbx), %rdi
cvtss2sd 0xc(%rsp), %xmm0
leaq 0xaafc(%rip), %rsi      # 0x117ed
movb $0x1, %al
callq 0x21c0
movss 0xc(%rsp), %xmm0
ucomiss 0x947f(%rip), %xmm0     # 0x10184
jbe 0x69ee
movq (%rbx), %rcx
leaq 0xab01(%rip), %rdi      # 0x11816
pushq $0x34
popq %rsi
pushq $0x1
popq %rdx
callq 0x22b0
jmp 0x69ee
movq 0x10584(%rip), %rdx     # 0x172b0
movq (%r13), %rcx
leaq 0xab14(%rip), %rsi      # 0x1184b
leaq 0x40(%rsp), %rbx
movq %rbx, %rdi
xorl %eax, %eax
callq 0x2290
jmp 0x6d66
movq (%r13), %rdx
cvtss2sd %xmm0, %xmm0
leaq 0xaafc(%rip), %rsi      # 0x11853
leaq 0x40(%rsp), %rbx
movq %rbx, %rdi
movb $0x1, %al
callq 0x2290
pushq $0x21
popq %rsi
movq %rbx, %rdi
callq 0x2724
pushq $0x1
popq %rdi
callq 0x22a0